如何使用JPA / Hibernate在孩子的id中引用父母的ID?

时间:2016-08-08 21:46:18

标签: java oracle hibernate jpa

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

我还有另一张表(MY_TABLE_B),它引用原始表格的主键。当我尝试将两者都保存到我的Oracle数据库时,我得到org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save()

我想要完成的任务:每当我将对象持久化到MY_TABLE_A时,我希望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;
    // 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
}

Service Layer片段,我在Oracle中为每个条目插入新条目:

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

有关firstClassService的insert()的详细信息:

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

insert()

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

更新

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

二等:

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

3 个答案:

答案 0 :(得分:2)

映射应如下所示:

@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选项设置,您只需要调用以保存firstClass:相关的secondClass将自动保留 - 假设您在内存模型中设置了关系的两侧,即

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

答案 1 :(得分:1)

angular-cache添加到第二个类的ID中。

@GeneratedValue(strategy=GenerationType.IDENTITY)

答案 2 :(得分:1)

根据你的描述,你似乎有一个ManytoOne关系,因为你的表B引用了表A,那么它的逻辑说A有一个Bs列表,所以为什么不利用ORM实际上是什么为什么不在A中保留一个引用,如:

@OneToMany(mappedBy="aa")
private List<B> bs;

并在另一个实体中使用注释:

@ManyToOne
@JoinColumn(name = "myId" , referencedColumnName = "id")
private A aa;

结合Jens的建议,请参阅OracleDialect does not support identity key generation