Hibernate,由父表中的序列生成的外键的映射

发布于 2024-09-24 08:01:06 字数 1151 浏览 5 评论 0原文

我在数据库和代表与 hibernate 关系的 java 对象中有 1:n 关系。 父表的主键是用数据库序列生成的, 子对象使用父对象的主键作为外键。

我创建一个新的父对象,其中包括一组新的子对象。 然后我尝试用一个来持久化所有对象

session.save(contract);

父对象的存储工作没有问题,但是一旦我添加子对象,我就会得到一个异常

...not-null属性引用了一个null或瞬态值...

因为子对象中缺少 FK。

是否有一个映射告诉 hibernate 使用父对象新生成的 PK 作为子对象中的 FK,或者我是否必须通过手动设置的 FK 单独保存子对象?

映射父对象: …………

@Id 
@Column(name="ID", unique=true, nullable=false, precision=22, scale=0)
@SequenceGenerator(name="sequence_seq", sequenceName="SEQ_CONTRACT")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence_seq")
public long getId() {
    return this.id;
}

对象

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="contract")
    public Set<ContractSearchtags> getContractSearchtagses() {
        return this.contractSearchtagses;
    }

映射

……

@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="CONTRACT_ID", nullable=false)
    public Contract getContract() {
        return this.contract;
    }

I have a 1:n relation in the database and java objects that represent the relation with hibernate.
The primary key of the parent table is generated with a database sequence,
the child object uses the primary key of the parent object as foreign key.

I create a new parent object including a set of new child objects.
Then I try to persist all objects with one single

session.save(contract);

The storage of the parent object works without problems, but as soon as I add child objects I get an exception

... not-null property references a null or transient value ...

because of the missing FK in the child object.

Is there a mapping which tells hibernate to use the newly generated PK of the parent object as FK in the child objects, or do I have to persist the child objects separately with the FK manually set?

mapping parent object:
...

@Id 
@Column(name="ID", unique=true, nullable=false, precision=22, scale=0)
@SequenceGenerator(name="sequence_seq", sequenceName="SEQ_CONTRACT")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence_seq")
public long getId() {
    return this.id;
}

...

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="contract")
    public Set<ContractSearchtags> getContractSearchtagses() {
        return this.contractSearchtagses;
    }

...

mapping of child object

...

@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="CONTRACT_ID", nullable=false)
    public Contract getContract() {
        return this.contract;
    }

...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趁年轻赶紧闹 2024-10-01 08:01:06

是否有一个映射告诉hibernate使用父对象新生成的PK作为子对象中的FK,或者我是否必须手动设置FK来单独持久化子对象?

没有特定的映射可用于此目的。但是,我怀疑您在构建双向关联时没有正确设置“链接的两侧”。你需要做这样的事情:

Contract contract = new Contract();
...
ContractSearchtags tag = new ContractSearchtags();
...
contract.getContractSearchtagses().add(tag);
tag.setContract(contract);

session.save(contract);

开发人员通常使用“链接管理方法”来正确设置双方(在Contract中):

public void addToContractSearchtagses(ContractSearchtags tag) {
    contractSearchtagses.add(tag);
    tag.setContract(this);
}

然后代码变成:

Contract contract = new Contract();
...
ContractSearchtags tag = new ContractSearchtags();
...
contract.addToContractSearchtagses(tag);

session.save(contract);

Resources

Is there a mapping which tells hibernate to use the newly generated PK of the parent object as FK in the child objects, or do I have to persist the child objects separately with the FK manually set?

There is no particular mapping to use for this. However, I suspect that you're not setting "both sides of the link" correctly when building your bidirectional association. You need to do something like this:

Contract contract = new Contract();
...
ContractSearchtags tag = new ContractSearchtags();
...
contract.getContractSearchtagses().add(tag);
tag.setContract(contract);

session.save(contract);

Developers typically use "link management methods" to correctly set both sides (in Contract):

public void addToContractSearchtagses(ContractSearchtags tag) {
    contractSearchtagses.add(tag);
    tag.setContract(this);
}

And then the code becomes:

Contract contract = new Contract();
...
ContractSearchtags tag = new ContractSearchtags();
...
contract.addToContractSearchtagses(tag);

session.save(contract);

Resources

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文