Question

I have a OneToOne relationship between two tables, as shown below:

PreRecordLoad.java:

@OneToOne(mappedBy="preRecordLoadId",cascade = CascadeType.ALL)
private PreRecordLoadAux preRecordLoadAux;

PreRecordLoadAux.java:

@JoinColumn(name = "PRE_RECORD_LOAD_ID", referencedColumnName = "PRE_RECORD_LOAD_ID")
@OneToOne
private PreRecordLoad preRecordLoadId;

I'm using this method to pull back the PreRecordLoad object:

public PreRecordLoad FindPreRecordLoad(Long ID)
{
    print("Finding " + ID + "f");

    Query query;
    PreRecordLoad result = null;
    try
    {
        query = em.createNamedQuery("PreRecordLoad.findByPreRecordLoadId");
        query.setParameter("preRecordLoadId", ID);
        result = (PreRecordLoad)query.getSingleResult();
        //result = em.find(PreRecordLoad.class, ID);
    }
    catch(Exception e)
    {
        print(e.getLocalizedMessage());
    }

    return result;
}

The '+ "f"' is to see if the passed value somehow had something at the end. It didn't.

I originally used em.find, but the same issue occurred no matter which method I used.

I used to use a BigDecimal for the ID because it was the default, and noticed I was getting a precision difference when it worked, and when it didn't work. Specifically the precision was 4 when it didn't work, but 0 when it did. I couldn't work out why this was, so I changed the BigDecimal to a Long, as I never really needed it to be a BigDecimal anyway.

When I save the new PreRecordLoad and PreRecordLoadAux objects to the database (inserting them for the first time), and then try and run this method to recall the objects, it retrieves the PreRecordLoad, but the PreRecordLoadAux is null. This is despite the entry being in the database and what looks to be full committed, as I can access it from SQLDeveloper, which is a separate session.

However, if I stop and re-run the application, then it successfully pulls back both objects. The ID being passed is the same both times, or at least appears to be.

Anyway suggestions would be greatly appreciated, thankyou.

Edit:

Here is the code for when I am persisting the objects into the DB:

    if(existingPreAux==null) {
        try {
            preLoad.setAuditSubLoadId(auditLoad);
            em.persist(preLoad);
            print("Pre Record Load entry Created");

            preAux.setPreRecordLoadId(preLoad);
            em.persist(preAux);
            print("Pre Record Load Aux entry Created");
        }
        catch(ConstraintViolationException e) {
            for(ConstraintViolation c : e.getConstraintViolations()) {
                System.out.println (c.getPropertyPath() + " " + c.getMessage());
            }
        }
    }
    else {
        try {
            preLoad.setPreRecordLoadId(existingPreLoad.getPreRecordLoadId());
            preLoad.setAuditSubLoadId(auditLoad);
            em.merge(preLoad);
            print("Pre Record Load entry found and updated");

            preAux.setPreRecordLoadAuxId(existingPreAux.getPreRecordLoadAuxId());
            preAux.setPreRecordLoadId(preLoad);
            em.merge(preAux);
            print("Pre Record Load Aux entry found and updated");
        }
        catch(ConstraintViolationException e) {
            for(ConstraintViolation c : e.getConstraintViolations()) {
                System.out.println (c.getPropertyPath() + " " + c.getMessage());
            }
        }
    }

That's in a method, and after that code, the method ends.

Était-ce utile?

La solution

It's your responsibility to maintain the coherence of the object graph. So, when you do preAux.setPreRecordLoadId(preLoad);, yo must also do preLoad.setPreRecordLoadAux(preAux);.

If you don't, then every time you'll load the preAux from the same session, it will be retrieved from the first-level cache, and will thus return your incorrectly initialized instance of the entity.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top