Question

I have an application using Eclipselink 2.4.0, in which I've started using a generated surrogate key. My EJB annotations look like this:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "reformatFileId")
@SequenceGenerator(name = "reformatFileId", sequenceName = "REFORMAT_FILE_ID_SEQ", allocationSize = 1)
@Basic(optional = false)
@NotNull
@Column(name = "FILE_ID")
private Long fileId;

My logic to persist the EJB, after I instantiate it, looks like this:

    try {
        EntityManager em = getEntityManager();
        em.persist(entity);
        em.flush();
    } catch (ConstraintViolationException ex) {
        for (ConstraintViolation cv : ex.getConstraintViolations())
            LOGGER.log(Level.SEVERE, "Constraint violation persisting {0}: {1}", new Object[]{entity.getClass(), cv.getMessage()});
        throw ex;
    }

When I create my object, I immediately need to get the fileId value so I can create records in a child table that uses the fileId as a foreign key. However, I'm finding the fileId value is still null.

I've tried a simple workaround, by discarding the original object and querying a new one (based on the unique combination of columns for which the fileId is a surrogate key), and I think I must be getting a cached object, because I'm still getting an EJB instance with a null fileId.

I've tried updating to Eclipselink 2.4.1 in case this was a JPA bug, but that hasn't helped.

I've also tried adding a call to em.refresh(entity) in my commit logic, but my understanding is that refreshing acts on the primary key, so this understandably hasn't fixed the problem.

I'm currently looking into invalidating the cache for this object and then reloading it, but that seems like an awful kludge. From what I've read of JPA, this should just work as I expect it to work.

Any suggestions would be most appreciated.

Steve

Was it helpful?

Solution 2

I ended up having to do a brute-force work-around of committing the object, then reinstantiating it from scratch. It's not pretty, but it works. I still can't explain why it is not honoring the documented behavior for a JPA generated sequence. It may be a bug in EclipseLink 2.4.0, but I haven't verified this.

OTHER TIPS

EclipseLink will assign the id value on the persist() call for SEQUENCE generation. For IDENTITY generation it cannot be assign until flush or commit.

You should see the value after your persist call. Are you getting any errors? You have a @NotNull validation constraint, this could be causing an error. Try printing the value of the id after the persist call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top