Hibernate:Criteria 和 HQL 的映射行为之间的差异
Hibernate: Difference between mapping behaviour of Criteria and HQL
Hibernate 和 HQL 的标准 API 在加载 Class 映射方面表现不同。
如果我从 XML 加载映射,两种方式都能够加载实体 class。但是,如果我使用注释,则只有 Criteria api 能够加载映射。请帮助我了解其中的原因。
我正在使用 Hibernate 版本:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
休眠配置
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/demo</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.pool_size">1</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.archive.autodetection">class, hbm</property>
<!--<mapping class="com.mk.hibernate.User" resource="User.hbm.xml"/>-->
<mapping class="com.mk.hibernate.User"/>
</session-factory>
</hibernate-configuration>
Hibernate 映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping
xmlns="http://www.hibernate.org/xsd/hibernate-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hibernate.org/xsd/hibernate-mapping
http://www.hibernate.org/xsd/hibernate-mapping/hibernate-mapping-4.0.xsd">
<class name="com.mk.hibernate.User" table="USERS">
<id name="username" column="USERNAME" type="java.lang.String" >
<generator class="assigned"></generator>
</id>
<property name="firstname" column="FIRSTNAME" type="java.lang.String"/>
<property name="lastname" column="LASTNAME" type="java.lang.String"/>
<property name="doj" column="DOJ" type="java.util.Date"/>
</class>
</hibernate-mapping>
我有一个实体
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Date;
import java.util.Objects;
@Entity(name = "USERS")
public class User implements java.io.Serializable {
@Id
@Column(name = "USERNAME")
private String username;
@Column(name = "FIRSTNAME")
private String firstname;
@Column(name = "LASTNAME")
private String lastname;
@Column(name = "DOJ")
private Date doj;
...
...
我有两种方法可以为此实体获取数据
public List<User> getAllUsersByCriteria() {
Session session = sessionFactory.openSession();
Criteria cr = session.createCriteria(User.class);
List<User> users = cr.list();
System.out.println(users.size());
session.close();
return users;
}
public List<User> getAllUsers() {
Session session = sessionFactory.openSession();
List<User> users = session.createQuery(" from User").list();
session.close();
return users;
}
当我执行以下代码时
System.out.println("====By Criteria===");
controller.getAllUsersByCriteria().forEach(u -> {
System.out.println(u.getFirstname());
});
System.out.println("====By Query===");
controller.getAllUsers().forEach(u -> {
System.out.println(u.getFirstname());
});
我收到以下异常
====By Criteria===
Hibernate: select this_.USERNAME as USERNAME1_0_0_, this_.DOJ as DOJ2_0_0_, this_.FIRSTNAME as FIRSTNAM3_0_0_, this_.LASTNAME as LASTNAME4_0_0_ from USERS this_
2
User1
User2
====By Query===
problem creating session factory!
org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped [ from User]
at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:96)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:234)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836)
at com.mk.hibernate.UserServiceImpl.getAllUsers(UserServiceImpl.java:33)
at com.mk.hibernate.UserControllerImpl.getAllUsers(UserControllerImpl.java:27)
at Main.main(Main.java:35)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:95)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:338)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3678)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 10 more
Feb 26, 2018 5:32:27 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/demo]
试试这个,只需更改 class 名称,它对我有用 ::
List<University> users = entityManager.createQuery(" from University").getResultList();
System.out.println("University size = " + users.size());
for (University university : users) {
System.out.println("University Name = " + university.getName());
}
我认为您误解了 @Entity
注释的 name
属性 应该如何工作。
@Entity(name = "USERS")
将 User 实体的 hql 名称映射到 USERS,如果没有值,则默认为类名。因此,一个有效的 hql 查询将是 "from USERS"
而不是 "from User"
.
您希望注释 @Table(name = "USERS")
定义实体的 table 名称。
尝试将映射注释更改为以下内容:
@Entity
@Table(name = "USERS")
public class User implements java.io.Serializable {
....
}
Hibernate 和 HQL 的标准 API 在加载 Class 映射方面表现不同。 如果我从 XML 加载映射,两种方式都能够加载实体 class。但是,如果我使用注释,则只有 Criteria api 能够加载映射。请帮助我了解其中的原因。
我正在使用 Hibernate 版本:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
休眠配置
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/demo</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.pool_size">1</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.archive.autodetection">class, hbm</property>
<!--<mapping class="com.mk.hibernate.User" resource="User.hbm.xml"/>-->
<mapping class="com.mk.hibernate.User"/>
</session-factory>
</hibernate-configuration>
Hibernate 映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping
xmlns="http://www.hibernate.org/xsd/hibernate-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hibernate.org/xsd/hibernate-mapping
http://www.hibernate.org/xsd/hibernate-mapping/hibernate-mapping-4.0.xsd">
<class name="com.mk.hibernate.User" table="USERS">
<id name="username" column="USERNAME" type="java.lang.String" >
<generator class="assigned"></generator>
</id>
<property name="firstname" column="FIRSTNAME" type="java.lang.String"/>
<property name="lastname" column="LASTNAME" type="java.lang.String"/>
<property name="doj" column="DOJ" type="java.util.Date"/>
</class>
</hibernate-mapping>
我有一个实体
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Date;
import java.util.Objects;
@Entity(name = "USERS")
public class User implements java.io.Serializable {
@Id
@Column(name = "USERNAME")
private String username;
@Column(name = "FIRSTNAME")
private String firstname;
@Column(name = "LASTNAME")
private String lastname;
@Column(name = "DOJ")
private Date doj;
...
...
我有两种方法可以为此实体获取数据
public List<User> getAllUsersByCriteria() {
Session session = sessionFactory.openSession();
Criteria cr = session.createCriteria(User.class);
List<User> users = cr.list();
System.out.println(users.size());
session.close();
return users;
}
public List<User> getAllUsers() {
Session session = sessionFactory.openSession();
List<User> users = session.createQuery(" from User").list();
session.close();
return users;
}
当我执行以下代码时
System.out.println("====By Criteria===");
controller.getAllUsersByCriteria().forEach(u -> {
System.out.println(u.getFirstname());
});
System.out.println("====By Query===");
controller.getAllUsers().forEach(u -> {
System.out.println(u.getFirstname());
});
我收到以下异常
====By Criteria===
Hibernate: select this_.USERNAME as USERNAME1_0_0_, this_.DOJ as DOJ2_0_0_, this_.FIRSTNAME as FIRSTNAM3_0_0_, this_.LASTNAME as LASTNAME4_0_0_ from USERS this_
2
User1
User2
====By Query===
problem creating session factory!
org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped [ from User]
at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:96)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:234)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836)
at com.mk.hibernate.UserServiceImpl.getAllUsers(UserServiceImpl.java:33)
at com.mk.hibernate.UserControllerImpl.getAllUsers(UserControllerImpl.java:27)
at Main.main(Main.java:35)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:95)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:338)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3678)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 10 more
Feb 26, 2018 5:32:27 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/demo]
试试这个,只需更改 class 名称,它对我有用 ::
List<University> users = entityManager.createQuery(" from University").getResultList();
System.out.println("University size = " + users.size());
for (University university : users) {
System.out.println("University Name = " + university.getName());
}
我认为您误解了 @Entity
注释的 name
属性 应该如何工作。
@Entity(name = "USERS")
将 User 实体的 hql 名称映射到 USERS,如果没有值,则默认为类名。因此,一个有效的 hql 查询将是 "from USERS"
而不是 "from User"
.
您希望注释 @Table(name = "USERS")
定义实体的 table 名称。
尝试将映射注释更改为以下内容:
@Entity
@Table(name = "USERS")
public class User implements java.io.Serializable {
....
}