首页 文章

Hibernate条件查询JPA条件查询

提问于
浏览
0

我正在迁移到Hibernate 5.2,因为不推荐使用createCriteria,我们计划将查询重写为JPA样式 . 我正面临一个问题(java.lang.IllegalArgumentException:不是实体),其中相同的代码使用hibernate criteria方法 .

使用hibernate标准

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();

获取JPA标准的“java.lang.IllegalArgumentException:非实体”

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();

你能告诉我JPA代码有什么问题吗?

Update 当我们有基类(抽象)并且实际的实体类是具体的子类时,就会出现这个问题 . 早期的hibernate标准,即使我传递基类,检索结果也没有问题 .

但在迁移到JPA标准后,我无法传递基类 . 这可以在JPA中管理 .

提前致谢 .

1 回答

  • 0

    如果你在hibernate中使用注释,那么你将在refClass上定义一个 @Entity . 就像你必须像这样映射实体:

    @Entity
    @Table(name = "tableName")
    public class ClassOfTable implements Serializable,Cloneable {
    
      public ClassOfTable () {
      }
    
      @Column(name = "column1")
      private Boolean member1;
    
      @Column(name = "column2")
      private String member2;
    
    }
    

    并且您将在创建 sessionFactory 时传递此类 . 如果你在创建sessionFactory时没有传递这个类,那么它将抛出一个异常,该类不是一个实体 .

    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();
    

    或者,如果使用Hibernate配置文件,则必须在hibernate.cfg.xml中指定hbm.xml的映射文件名,而someName.hbm.xml包含refClass的映射 .

    然后你创建会话工厂 .

    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();
    

    你的hibernate.cfg.xml必须包含(映射resourece)条目,其中定义了refClass mappiing .

    <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>
    

    并且您的hbm.xml必须具有refClass映射

    <?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>
    

相关问题