休眠条件查询到 JPA 条件查询
Posted
技术标签:
【中文标题】休眠条件查询到 JPA 条件查询【英文标题】:Hibernate criteria queries to JPA criteria queries 【发布时间】:2017-12-20 10:15:08 【问题描述】:我正在迁移到 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: Not an entity”
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代码有什么问题吗
更新 当我们有基类(抽象)并且实际的实体类是具体的子类时会看到这个问题。早先使用hibernate条件,即使我通过了基类,检索结果也没有问题。
但是在迁移到 JPA 标准后,我无法通过基类。这可以在 JPA 中管理吗?
提前致谢。
【问题讨论】:
什么是 refClassName?你应该使用泛型。 refClassName 是 Class 对象。 (例如 Employee.class)。我正在根据类名加载类。类 refClassName = null;尝试 refClassName = Class.forName(className); 捕捉 (ClassNotFoundException cnf) cnf.printStackTrace(); 遇到异常时传递的是哪种类型?你能发布堆栈跟踪吗 您可能必须将您的实体包含在 persistence.xml 中,例如参见 ***.com/questions/1780341/… 我正在传递 com.xxxx.xxxx.xxxx.xxxx.Neighbor。 Stacktrace 是:java.lang.IllegalArgumentException:不是实体:org.hibernate.metamodel.internal.MetamodelImpl.entity(MetamodelImpl.java:456) 的 org.hibernate.query 的类 com.xxxx.xxxx.xxxx.xxxx.Neighbor .criteria.internal.QueryStructure.from(QueryStructure.java:126) at org.hibernate.query.criteria.internal.CriteriaQueryImpl.from(CriteriaQueryImpl.java:153) 【参考方案1】:如果您在 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 s-s-rb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
SessionFactory sessionFactory = configuration.buildSessionFactory(s-s-rb.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>
【讨论】:
以上是关于休眠条件查询到 JPA 条件查询的主要内容,如果未能解决你的问题,请参考以下文章