简体   繁体   中英

How to select parent objects without children in Hibernate?

I have the following entities, parent and child, it's possible that a parent object doesn't have children. How to select parents that don't have children in hibernate? It would be similar to the not existing clause in SQL. Here are my entities:

@Entity
@Table(name = "PARENT")
public class Parent implements Serializable {

    @Id
    @Column(name="PARENT_ID")
    private Long parentId;

    @Column(name="NAME")
    private String name;

    @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
    Set<Child> children;
}
@Entity
@Table(name = "CHILD")
public class Child implements Serializable {

    @Id
    @Column(name="CHILD_ID")
    private Long childId;

    @Column(name="NAME")
    private String name;

    @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
    @JoinColumn(name="PARENT_ID", nullable=false, updatable=false)
    private Parent parent;
}

My query:

public List<Parent> getParentsNotHavingChildren() {
    Session session = this.sessionFactory.getCurrentSession();
    Transaction txn = session.beginTransaction();
    List<Parent> result = null;
    Criteria criteria = session.createCriteria(Parent.class)
            .add(Restrictions.eq("children", null));
    result = criteria.list();
    txn.commit();
    if (session.isOpen()) {
        session.close();
    }
    log.info(String.format("Get %s parents", result.size()));
    return result;
}

Then I got errors

org.hibernate.exception.GenericJDBCException: could not execute query
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.loader.Loader.doList(Loader.java:2545)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
    at HibernateParentDao.getParentsNotHavingChildren(HibernateParentDao.java:42)
Caused by: java.sql.SQLException: Missing IN or OUT parameter at index:: 1
    at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
    at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:110)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:171)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
    at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:1737)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3376)
    at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3425)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1202)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
    at org.hibernate.loader.Loader.doQuery(Loader.java:802)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2542)

I'm sure my criteria isn't correct, but I can't find what should be the right way of this type of query. Any help would be very appreciated!

To test an attribute to be null, then use isNull ... change

Criteria criteria = session.createCriteria(Parent.class)
        .add(Restrictions.eq("children", null));

for

Criteria criteria = session.createCriteria(Parent.class)
        .add(Restrictions.isNull("children"));

Otherwise, Hibernate will expect a non-null value to perform the eq

This is a simple criteria to select a parent with no children (for one to many relations you should use isEmpty ).

Criteria criteria = currentSession().createCriteria(Parent.class);
criteria.add(Restrictions.isEmpty("children"));
return criteria.list();

And by the way, for a simple "select" query you don't need to create a transaction . Just with the three lines above it should be enough.

The other answer may work but only in one to one relationships. Hope it works!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM