Search code examples
javahibernatehibernate-mappingjpa-2.1

How to cope with "orphaned" rows in JPA @OneToOne mapping


I am attempting to develop a Standalone Java application that uses JPA (Hibernate 4.3).

This accesses a DB2 v10 zos database.

Two of my entities have a @OneToOne mapping that I want to LAZY Load.

The issue I have is that the Parent table has rows that do not exist on the child table.

I am using

@OneToOne(optional = false, fetch = FetchType.LAZY)

Which works fine where the joining column value exists in both tables, however my data is inconsistent and I cases where values only exist in the parent table.

I have tried adding

@NotFound(action=NotFoundAction.IGNORE)

To my @OneToOne mapping to no avail.

Is it possible to LAZY LOAD @OneToOne relationships where there isnt always a row on each table?

My two entities have these annotations for OneToOne mapping

@Entity
@Table(name = "TABLE0001")
@BatchSize(size = 100)
public class Table_0001 {

    /**
     * Related Table
     */
    @OneToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "PTY_ID")
    @BatchSize(size = 100)
    private Table_0002 table0002;

    public Table_0002 getTable0002() {
        return table0002;
    }

    public void setTable0002(final Table_0002 table0002) {
        this.table0002 = table0002;
    }

}

@Entity
@Table(name = "TABLE0002")
@BatchSize(size = 100)
public class Table_0002 {

}

I need LAZY loading between these two entities.

I am retrieving a list of Table_0001 and then want to get Table_0002 in batches of 100. This would all work with the annotations shown IF there werent IDs existing on Table_0001 that do not exist on Table_0002.

This is the java code I use to get the list of Table_0001

private static Collection<? extends Table_0001> getAllModelsIterable(final String filter, final int offset, final int max) {

    final CriteriaBuilder criteriaBuilder = PersistenceManager.INSTANCE.getCriteriaBuilder();

    final CriteriaQuery<Table_0001> criteriaQuery = criteriaBuilder.createQuery(Table_0001.class);
    Root<Table_0001> personRoot = criteriaQuery.from(Table_0001.class);
    criteriaQuery.select(personRoot);
    criteriaQuery.where(criteriaBuilder.like(personRoot.get(Table_0001_.filter), filter));
    criteriaQuery.orderBy(criteriaBuilder.asc(personRoot.get("id")));

    final TypedQuery<Table_0001> typedQuery = entityManager.createQuery(criteriaQuery);
    typedQuery.setFirstResult(offset);
    typedQuery.setMaxResults(max);

    return typedQuery.getResultList();

}

Solution

  • here is some documentation about jpa and the optional attribute. It says:

    boolean optional (Optional) Whether the association is optional. If set to false then a non-null relationship must always exist. Default value: true Since: JPA 1.0

    What happens when you set the optional attribute to true?