繁体   English   中英

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

[英]How to reference a parent's id in a child's id with JPA/Hibernate?

给定一个表( MY_TABLE_A ),该表将在每次新插入时自动增加其ID(即数据库中的第一条记录的ID属性设置为1,第二条记录的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
}

我在其中为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);
}

UPDATE

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

映射应如下所示:

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

@GeneratedValue(strategy=GenerationType.IDENTITY)添加到第二类的ID。

@Id
@Column(name = "MY_ID")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer myId;
// more variables, getters/setters

从您的描述看来,您似乎具有一个ManytoOne关系,因为您的表B引用了表A,因此逻辑上说A有一些B的列表,因此为什么不利用ORM的实际含义,又为什么不保留引用呢?如:

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

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

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

结合Jens的建议,请参见OracleDialect不支持身份密钥生成

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM