Java 如何使用JPA/Hibernate在子id中引用父id?
给定一个表MY_table_a,它在每次新插入时自动增加其id,即数据库中的第一条记录的id属性为1,第二条记录的id属性设置为2,第三条记录的id属性设置为3。我说的ID是表的主键 我还有另一个表MY_table_B,引用是原始表的主键。当我尝试将这两个类都持久化到Oracle数据库时,会得到一个org.hibernate.id.IdentifierGenerationException:在调用save之前,必须手动分配此类的id 我想要完成的是:每当我将一个对象持久化到我的_TABLE_A时,我希望我的_TABLE_B插入一个与我的_TABLE_A获得的ID相同的对象,因为它是自动递增的,在插入之前不知道下一个值是什么。为了澄清,表A中的一个id在表B中应该只有一个匹配的id 下面是我的一些代码片段: 头等舱:Java 如何使用JPA/Hibernate在子id中引用父id?,java,oracle,hibernate,jpa,Java,Oracle,Hibernate,Jpa,给定一个表MY_table_a,它在每次新插入时自动增加其id,即数据库中的第一条记录的id属性为1,第二条记录的id属性设置为2,第三条记录的id属性设置为3。我说的ID是表的主键 我还有另一个表MY_table_B,引用是原始表的主键。当我尝试将这两个类都持久化到Oracle数据库时,会得到一个org.hibernate.id.IdentifierGenerationException:在调用save之前,必须手动分配此类的id 我想要完成的是:每当我将一个对象持久化到我的_TABLE_A时
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_A")
@Component
public class FirstClass implements Serializable {
@Id
@SequenceGenerator(name = "MY_SEQ", sequenceName = "MY_SCHEMA.MY_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ")
@Column(name = "MY_ID")
private Integer myId;
// more variables, getters/setters
}
二等舱:
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_B")
@SecondaryTable(name = "MY_SCHEMA.MY_TABLE_A", pkJoinColumns = @PrimaryKeyJoinColumn(name = "MY_ID", referencedColumnName = "MY_ID"))
@Component
public class SecondClass {
@Id
@Column(name = "MY_ID")
private Integer myId;
// more variables, getters/setters
}
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_B")
@SecondaryTable(name = "MY_SCHEMA.MY_TABLE_B", pkJoinColumns = @PrimaryKeyJoinColumn(name = "MY_ID", referencedColumnName = "MY_ID"))
@Component
public class SecondClass implements Serializable {
@Id
@JoinColumn(name = "MY_ID", referencedColumnName = "MY_ID")
@OneToOne
private Integer restRequestId;
}
我在Oracle中为每个服务层插入新条目的服务层代码段:
firstClassService.insert();
secondClassService.insert();
有关为firstClassService插入的详细信息:
public void insert() {
FirstClass obj = new FirstClass();
getCurrentSession().persist(obj);
}
public void insert() {
SecondClass obj = new SecondClass();
getCurrentSession().persist(obj);
}
为secondClassService插入:
public void insert() {
FirstClass obj = new FirstClass();
getCurrentSession().persist(obj);
}
public void insert() {
SecondClass obj = new SecondClass();
getCurrentSession().persist(obj);
}
更新
头等舱现在是什么样子:
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_A")
@Component
public class FirstClass implements Serializable {
@Id
@SequenceGenerator(name = "MY_SEQ", sequenceName = "MY_SCHEMA.MY_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ")
@Column(name = "MY_ID")
@OneToOne(mappedBy = "myId")
private Integer myId;
}
二等舱:
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_B")
@SecondaryTable(name = "MY_SCHEMA.MY_TABLE_A", pkJoinColumns = @PrimaryKeyJoinColumn(name = "MY_ID", referencedColumnName = "MY_ID"))
@Component
public class SecondClass {
@Id
@Column(name = "MY_ID")
private Integer myId;
// more variables, getters/setters
}
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_B")
@SecondaryTable(name = "MY_SCHEMA.MY_TABLE_B", pkJoinColumns = @PrimaryKeyJoinColumn(name = "MY_ID", referencedColumnName = "MY_ID"))
@Component
public class SecondClass implements Serializable {
@Id
@JoinColumn(name = "MY_ID", referencedColumnName = "MY_ID")
@OneToOne
private Integer restRequestId;
}
将@GeneratedValuestrategy=GenerationType.IDENTITY添加到第二个类的id中
@Id
@Column(name = "MY_ID")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer myId;
// more variables, getters/setters
从你的描述来看,似乎你有一个多单关系,因为你的表B引用了表a,那么说a在某种程度上有一个B列表是合乎逻辑的,那么为什么不利用ORM实际是什么,为什么不在a中保留一个引用,例如:
@OneToMany(mappedBy="aa")
private List<B> bs;
结合Jens的建议,请参见映射应如下所示:
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_A")
@Component
public class FirstClass implements Serializable {
@Id
@SequenceGenerator(name = "MY_SEQ", sequenceName = "MY_SCHEMA.MY_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ")
@Column(name = "MY_ID")
private Long myId;
@OneToOne(mappedBy = "firstClass", cascade = CascadeType.ALL)
private SecondClass secondClass;
}
@Entity
@Table(name = "MY_SCHEMA.MY_TABLE_B")
@Component
public class SecondClass implements Serializable {
@Id
@JoinColumn(name = "MY_ID", referencedColumnName = "MY_ID")
@OneToOne
private FirstClass firstClass;
}
设置Cascade选项后,您只需调用save firstClass:关联的secondClass将自动持久化-假设您在内存模型中设置了relationhsip的两侧,即
firstClass.setSecondClass(secondClass);
secondClass.setFirstClass(firstClass);
添加时,我得到以下错误:org.hibernate.MappingException:org.hibernate.dialent.identity.IdentityColumnSupportImpl不支持标识键生成如果有帮助,我的id在第二个类使用的表中没有设置为自动递增。请参见此处:我为问题添加了更多背景信息,这将是一个一对一的关系,因为表a中只有一个id在表B中应该有一个对应的单个id,即表a中的id 100在表BSame应用中应该只有一个id 100,只需删除列表声明并将其作为单个bean属性执行即可,将oneToMany和ManyToOne分别更改为OneToOne尝试准确添加,但获得org.hibernate.AnnotationException:@Columns不允许在@OneToOne属性上使用:抱歉,我已经这样做了几个小时,只是没有点击我。我更新了我的问题,以反映您和Jens推荐的代码以及任何相关链接谢谢-这有助于我更好地理解这个概念。我现在面临一个org.hibernate.AnnotationException:Unknown mappedBy in:mypackage.mysubpackage.FirstClass.secondClass,引用属性Unknown:mypackage.mysubpackage.secondClass.FirstClass?这可能是一个配置问题吗?确保类在持久性xml中正确注册,检查实体注释是否存在于两个类中。我还可以告诉你,你正在使用不太复杂的类来表示你的问题,看看实际的类会很有用。谢谢大家!它现在工作得很好。我把你们每个人都有的东西拼凑在一起,我进一步研究了文档,这一切都是有意义的:@DanielArechiga