Reputation: 133
Please help! It has already taken me a day, and I am no closer to resolving the issue. My set up is as follows:
What I am doing is I am persisting an entity that has an @OneToOne mapping with a child entity. Once the record is in the database, I am running a select and successfully selecting the newly inserted record. However, the child entity is null.
My goal is to only insert the parent record, because the child record is already in the DB.
Question: what do I need to change to cause the child record to be populated?
I have an entity that I persist:
EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
em.persist(timeSheet);
em.getTransaction().commit();
}
The entity contains @OneToOne:
@Entity
@Cache(expiry=-1)
@Table(name="TIME_SHEET")
public class TimeSheet implements Serializable {
private static final long serialVersionUID = 1L;
@OneToOne(fetch=FetchType.EAGER)
@JoinColumns({
@JoinColumn(name="PROJECT_ID", referencedColumnName="PROJECT_ID", nullable = false, insertable=false, updatable=false),
@JoinColumn(name="COMPANY_ID", referencedColumnName="COMPANY_ID", nullable = false, insertable=false, updatable=false)
})
private Project project;
public Project getProject() {
return project;
}
The child entity is:
@Entity
@Cache(expiry=-1)
@Table(name="PROJECT")
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ProjectPK id;
After "TimeSheet" is persisted and selected, "Project" is null. What should I do to ensure that "Project" is populated?
Thank you!
Upvotes: 0
Views: 2073
Reputation: 6500
You should set the cascade policy correctly.
@OneToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-hibspec-cascade
Cascade policy dictates what to do with associated entities when you perform a persistence action on the parent entity.
Upvotes: 1
Reputation: 21145
As Ryan points out, you need to maintain the reference in TimeSheet to the Project. This is because the TimeSheet is cached. So you can either set the relationship by reading in the existing project when creating the TimeSheet, or by refreshing the TimeSheet after the transaction commits so that it gets built.
The code you have shown sets the TimeSheet->Project relationship fields are read only and doesn't show how the foriegn keys are populated. Make sure that these are actually set when inserting the TimeSheet through other mappings or it maybe that the TimeSheet legitimately doesn't have a Project - though the fields seem to have a not-null constraint.
Upvotes: 0
Reputation: 128899
Well, in the code shown, you persist a TimeSheet without first setting a Project in it, so why would you expect it to have a Project when you load it? You should never expect your object model to look different after you load it than it did before you saved it. If it does look different, then you have a problem.
Upvotes: 1