我有一个使用Seam和JPA(休眠)持久化的对象模型。看起来像这样:
@Entity(name = "MyObject")
public class MyObject {
...
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_myobj")
@SequenceGenerator(name = "seq_myobj", sequenceName = "seq_myobj")
private Long id = null;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, optional = false)
@NotNull
private MySubObject subObjA=null;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, optional = false)
@NotNull
private MySubObject subObjB=null;
...
}
@Entity(name = "MySubObject")
public class MySubObject {
...
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_mysubobj")
@SequenceGenerator(name = "seq_mysubobj", sequenceName = "seq_mysubobj")
private Long id = null;
}
我已经正确定义了
@ManyToOne
批注以及所有内容。但是,如果我尝试并保留同时设置了MyObject
和subObjA
的subObjB
实例,则会出现一个异常,说我有一个重复的主键,它是子obj的一个。什么会导致这种行为?这两个对象的标识符类型都设置为SEQUENCE,并且我设置一个或另一个都没有问题。只有同时设置了两者,我才能获得例外。我正在运行Seam 2.2,后端数据库是PostgreSQL。有什么想法会导致这种奇怪的行为?我认为这两个对象将作为同一事务的一部分被保留,并且正确的主键将被自动分配。就像我说的,如果我只设置一个对象,就没有问题。仅当我将它们都设置好时,才会发生这种情况。您能提供的任何帮助将不胜感激。
编辑我注意到在测试各种东西时有些奇怪的行为。如果我以编程方式创建MyObject并设置其所有属性(包括subObj),则它可以持久存在而不会出现问题。但是,如果我使用表单输入属性,则会收到错误消息。可能与交易有关吗?
最佳答案
如果在MySubObject
类中重写equals / hashCode,请确保这些方法仅检查代理键id
(在这种情况下,应完全避免使用它们)。
如果equals / hashCode方法可用于某些业务密钥属性,请在持久化之前确保这些密钥是唯一的。