Hibernate, mapping of foreign keys that have been generated by a sequence in the parent table
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 g开发者_运维技巧enerated 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;
}
...
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
- 1.2.6. Working bi-directional links (this one is the more obvious)
精彩评论