我正在迁移到Hibernate 5.2并且由于不推荐使用createCriteria,我们计划将查询重写为JPA样式。 我正面临一个问题(java.lang.IllegalArgumentException:不是实体),其中相同的代码使用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();
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中管理。
提前致谢。
答案 0 :(得分:0)
如果您在休眠模式下使用注释,则将在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>