簡體   English   中英

Hibernate條件查詢到JPA條件查詢

[英]Hibernate criteria queries to JPA criteria queries

我正在遷移到Hibernate 5.2,並且由於不贊成使用createCriteria,因此我們計划將查詢重寫為JPA樣式。 我遇到一個問題(java.lang.IllegalArgumentException:不是一個實體),其中相同的代碼正在使用休眠條件方法。

使用休眠條件

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代碼有什么問題嗎

更新當我們有基類(抽象)並且實際的實體類是具體的子類時,就會看到此問題。 早期使用休眠標准時,即使我通過了基類,在檢索結果時也沒有問題。

但是,在遷移到JPA標准之后,我無法通過基類。 可以在JPA中對其進行管理。

提前致謝。

如果您在休眠模式下使用批注,則會在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必須包含(映射資源)條目,在其中定義了refClass映射。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM