我正在使用Hibernate和JPA,并且有这样的关系:
@Entity
@Table(name = "first")
public class First {
...
@OneToMany(mappedBy = "first")
private List<Availability> availabilities;
...
}
@Entity
@Table(name = "second")
public class Second {
...
@OneToMany(mappedBy = "second")
private List<Availability> availabilities;
...
}
@Entity
@Table(name="availability")
public class Availability implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "first_id")
private First first;
@Id
@ManyToOne
@JoinColumn(name = "second_id")
private Second second;
@Column(name = "availability")
private Integer availability;
...
hashcode and equals
}
我想分别管理这3个实体。第一个和第二个工作正常,但是当我尝试merge()时,第三个postgresql获取一个空值而不是id和约束违规异常被抛出。为什么?我是否可以在此实体上使用合并向表中添加新行?
更新: 合并是这样的:
public Availability setAvailability(Availability a) {
return em.merge(a);
}
从前端对可用性进行反序列化(仅提及,“密钥”类的集合在其中分离)。
答案 0 :(得分:2)
您已经解决了问题,但我在此留下了一个建议,指出需要使用多列主键并且无法更改数据库的用户。
显然,在尝试合并时使用多个@Id注释会产生不一致:您指定所有字段,然后在合并期间注释@Id的字段获得指定空值(以及合并失败)。我可以猜到一个解释:hibernate并不期望有一个带有@Ids的非托管对象;但这只是一个问题,只有多列主键,所以它似乎是一个错误。
注意:调用 persist 而不是合并工作(但在某些情况下,您会复制行或获取数据库约束错误,因为在这种情况下仅在数据库级别检查主键)。
我使用@IdClass解决了类似的问题。在您的旧代码中,您必须:
那应该是它。抱歉迟到了3年,但如果你摆脱了多列主键,那么无论如何你现在处于一个更美好的世界。
我尝试了@EmbeddedId,但它破坏了其他一些要求(简单的json-&gt;对象转换和查询在SQL和HQL中都可以进行微调)。
答案 1 :(得分:0)
我通过避免使用复合ID解决了这个问题。在重新思考问题之后,我发现这个案例我实际上可以使用一个独特的约束。
@Entity
@Table(name = "availabilities", uniqueConstraints = { @UniqueConstraint(columnNames = {
"first_id", "second_id" }) })
@SequenceGenerator(initialValue = 1, name = "availabilities_sequence", sequenceName = "availabilities_sequence")
public class Availability implements IAvailability, Serializable {
private static final long serialVersionUID = -2977047920673617888L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "availabilities_sequence")
@Column(name = "id")
private Integer id;
@ManyToOne
@JoinColumn(name = "first_id", nullable=false)
private First first;
@ManyToOne
@JoinColumn(name = "second_id", nullable=false)
private Second second;
@Column(name = "availability", nullable=false)
private Integer availability;
...
}