user1004462
user1004462

Reputation: 133

Child entity is null after parent entity is persisted and selected

Please help! It has already taken me a day, and I am no closer to resolving the issue. My set up is as follows:

  1. Eclipse Indigo
  2. Eclipselink 2.3
  3. Apache Tomcat 6

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

Answers (3)

Basanth Roy
Basanth Roy

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

Chris
Chris

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

Ryan Stewart
Ryan Stewart

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

Related Questions