我有这样的代码:
Session session = HibernateSessionFactory.sessionFactory.openSession();
System.out.println("------------------" + session.get(User.class, (long) 10));
System.out.println("------------------" + session.createSQLQuery("SELECT * FROM diploma.tbl_users Where id = 10").addEntity(User.class).uniqueResult());
第一行返回null 第二个返回有效记录。
但如果我改变名额:
System.out.println("------------------" + session.createSQLQuery("SELECT * FROM diploma.tbl_users Where id = 10").addEntity(User.class).uniqueResult());
System.out.println("------------------" + session.get(User.class, (long) 10));
两行都返回正确的结果:
这是我的hibernate会话工厂:
public class HibernateSessionFactory {
public static SessionFactory sessionFactory = new Configuration().configure("/META-INF/hibernate.cfg.xml")
.buildSessionFactory();
}
为什么session.get(User.class, (long) 10))
会返回null?
更新 hibernate config:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/diploma</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.connection.charSet">UTF-8</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
.........................................
<mapping class="edu.test.entities.User" />
..................................
</session-factory>
User.java
@Entity
@Table(name = "tbl_Users")
public class User extends BaseEntity {
@NotEmpty
@Column(name = "Name")
private String name;
@NotEmpty
@Column(name = "Surname")
private String surname;
@NotEmpty
@Column(name = "Login")
private String login;
@NotEmpty
@Size(min=6, max=20)
@Column(name = "Password")
private String password;
@NotEmpty
@Column(name = "Email")
private String email;
@NotEmpty
@Column(name = "Phone")
private String phone;
@ManyToOne
@JoinColumn(name = "Role", nullable = false)
private Roles role;
// getters and setters
基础实体的Id字段
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue
private Long id;
更新2
问题出在映射文件@JoinColumn(name = "Role", nullable = false)
private Roles role;
我已经指定Role不能为null,而我尝试使用id 10检索的记录具有null Role外键。所以我改变nullable = true
并且它有效。
答案 0 :(得分:2)
Hibernate实现Identity Map PoEAA pattern,其中Hibernate会话扮演地图的角色。当您调用.addEntity()
时,加载的实体将与Hibernate会话关联。
然后,当您调用Hibernate会话的get方法时,它首先检查实体缓存并返回现有实体(如果存在)。
因此,在您致电get
的第一个声明中,实体尚未出现在实体地图中。在第二个代码段中,实体正在使用.addEntity()
方法进行缓存。
更新所以问题是该角色的引用是用nullable = false
声明的,并且在数据库中没有这样的角色。