简体   繁体   中英

Hibernate criteria queries to JPA criteria queries

I am migrating to Hibernate 5.2 and since createCriteria is deprecated, we plan to rewrite the queries to JPA-style. I am facing an issue (java.lang.IllegalArgumentException: Not an entity) where the same code is working with hibernate criteria method.

Working with hibernate criteria

Criteria criteria = getSession().createCriteria(className);

for (Map.Entry<String, Object> entry : matchingCriteria.entrySet()) {
    criteria.add(Expression.eq(entry.getKey(), entry.getValue()));
}
List objsMatchingCriteria = criteria.list();

Getting "java.lang.IllegalArgumentException: Not an entity" for JPA criteria

CriteriaBuilder cb = getSession().getCriteriaBuilder();
CriteriaQuery  cq = cbuilder.createQuery(refClassName);
Root root = cquery.from(refClassName);
cq.select(root);
List<Predicate> predicates = new ArrayList<>();
for (Map.Entry<String, Object> entry : matchingCriteria.entrySet()) {
    predicates.add(cb.equal(root.get(entry.getKey()), entry.getValue()));
}
cq.where(predicates.toArray(new Predicate[predicates.size()]));

List objsMatchingCriteria = 
    getSession().createQuery(cq).getResultList();

Can you let me know what is wrong with the JPA code

Update This problem is seen when we have base class (abstract) and the actual entity class is concrete child class. Earlier with hibernate criteria, even though I pass the base class, there is no problem in retrieving the results.

But after migrating to JPA criteria, I am not able to pass the base class. Can this be managed in JPA.

Thanks in advance.

If you are using annotations in hibernate then you'll define a @Entity on refClass. like you have to map entity like this :

@Entity
@Table(name = "tableName")
public class ClassOfTable implements Serializable,Cloneable {

  public ClassOfTable () {
  }

  @Column(name = "column1")
  private Boolean member1;

  @Column(name = "column2")
  private String member2;

}

and you'll pass this class while creating the sessionFactory . if you donot pass this class while creating the sessionFactory then it will throw an exception that class in not an entity.

StandardServiceRegistry standardRegistry =
        new StandardServiceRegistryBuilder().applySettings(createProperties(
            host, port, dbName, protocol, userName, password, minPoolSize, maxPoolSize)
            .getProperties()).build();

    MetadataSources sources = new MetadataSources(standardRegistry);
    annotatedClassNames.add(refClass.class);
    Metadata metaData = sources.getMetadataBuilder().build();
    return metaData.getSessionFactoryBuilder().build();

Or if you use Hibernate configuration file then you must specify the mapping file name of hbm.xml in your hibernate.cfg.xml and your someName.hbm.xml contain the mapping for refClass.

and then you create the session factory .

            Configuration configuration = new Configuration();
            configuration.configure("hibernate.cfg.xml");
            StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
            SessionFactory sessionFactory = configuration.buildSessionFactory(ssrb.build());
            Session session = sessionFactory.openSession();

your hibernate.cfg.xml must contain (mapping resourece) entry in which your refClass mappiing is defined.

<hibernate-configuration>
    <session-factory>
        <!-- JDBC connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/mediadb</property>
        <property name="connection.username">kodejava</property>
        <property name="connection.password">kodejava123</property>



        <!-- Mapping to hibernate mapping files -->
        <mapping resource="org/kodejava/example/hibernate/model/someName.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

and your hbm.xml must have refClass mapping

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name = "refClass" table = "some Class">

      <meta attribute = "class-description">
         This class contains the some detail. 
      </meta>

      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>

      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>

   </class>

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