如何在JPA / Hibernate中引用父级的ID在孩子的ID? [英] How to reference a parent's id in a child's id with JPA/Hibernate?

查看:123
本文介绍了如何在JPA / Hibernate中引用父级的ID在孩子的ID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个表( MY_TABLE_A ),它会在每次新插入时自动增加它的id(即数据库中的第一条记录具有ID属性1,第二条记录具有它ID属性设置为2,第三条记录将其ID属性设置为3)。我所说的ID是表的主键。



我还有另一个表( MY_TABLE_B ),原始表的主键。当我尝试同时保存到Oracle数据库时,出现 org.hibernate.id.IdentifierGenerationException:必须在调用save()



我要完成的任务:每当我将对象持久保存到 MY_TABLE_A 时, code> MY_TABLE_B 插入一个与 MY_TABLE_A 相同的ID的对象,因为它自动递增(不知道下一个值直到它被插入)。为了澄清,表A中的一个ID在表B中应该只有一个匹配的ID



以下是我的代码片段:



FirstClass:

  @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;
//更多变量,getters / setters
}






SecondClass:

  @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;
//更多变量,getters / setters
}






服务层片段,我在Oracle中为每个插入新条目:

  firstClassService.insert(); 
secondClassService.insert();






insert ) for firstClassService:

  public void insert(){
FirstClass obj = new FirstClass ();
getCurrentSession()。persist(obj);






insert() for secondClassService:

  public void insert(){
SecondClass obj = new SecondClass();
getCurrentSession()。persist(obj);
}

更新
$ b

FirstClass现在的样子:

  @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;






SecondClass:

  @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;


解决方案

映射应如下所示:

  @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;

$ b $ @实体
@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选项,您只需拨打电话保存firstClass:相关的secondClass会自动保存 - 假设你在你的内存模型中设置了relationhsip的双方,即

  firstClass.setSecondClass(二等); 
secondClass.setFirstClass(firstClass);


Given a table (MY_TABLE_A) that automatically increments it's id upon each new insertion (i.e. the first record in the database has it's ID attribute 1, the second record has it's ID attribute set to 2, the third record has it's ID attribute set to 3). The ID I am talking about is the table's primary key.

I also have another table (MY_TABLE_B) that reference's the original table's primary key. When I try to persist both to my Oracle database, I get a org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save()

What I want to accomplish: Whenever I persist an object to MY_TABLE_A, I want MY_TABLE_B to insert an object with the same ID that MY_TABLE_A gets since it's auto incremented (wouldn't know what the next value is until it's inserted). To clarify, one id in Table A should have only one matching ID in Table B

Here are some snippets of my code below:

FirstClass:

@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
}


SecondClass:

@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
}


Service Layer snippet where I insert new entries for each in Oracle:

firstClassService.insert();
secondClassService.insert();


Details on insert() for firstClassService:

public void insert() {
        FirstClass obj = new FirstClass();
        getCurrentSession().persist(obj);
}


insert() for secondClassService:

public void insert() {
        SecondClass obj = new SecondClass();
        getCurrentSession().persist(obj);
}

UPDATE

What FirstClass looks like now:

@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;
}


SecondClass:

@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;
}

解决方案

Mappings should be as below:

@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;
}

With the Cascade option set then you you will only need to make the call to save firstClass: the associated secondClass will be persisted automatically - assuming you set both sides of the relationhsip in your in-memory model i.e.

firstClass.setSecondClass(secondClass);
secondClass.setFirstClass(firstClass);

这篇关于如何在JPA / Hibernate中引用父级的ID在孩子的ID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆