4

我有这样的代码:

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

两行都返回正确的结果:

这是我的休眠会话工厂:

public class HibernateSessionFactory {

public static SessionFactory sessionFactory = new Configuration().configure("/META-INF/hibernate.cfg.xml")
        .buildSessionFactory();

 }

为什么session.get(User.class, (long) 10))返回 null ?

更新 休眠配置:

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

用户.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;,我已指定角色不能为空,并且我尝试使用 id 10 检索的记录具有空角色外键。所以我改变 nullable = true并且它起作用了。

4

1 回答 1

2

Hibernate 实现了身份映射 PoEAA 模式,其中 Hibernate 会话扮演映射的角色。当您调用.addEntity()时,加载的实体将与 Hibernate 会话相关联。

然后,当您调用 Hibernate 会话的 get 方法时,它首先检查实体缓存并返回现有实体(如果存在)。

因此,在您调用get实体的第一条语句中,实体映射中还没有出现。在第二个片段中,实体正在使用.addEntity()方法进行缓存。

更新所以问题是对角色的引用是用 声明的nullable = false,并且数据库中没有这样的角色。

另见:http ://martinfowler.com/eaaCatalog/identityMap.html

于 2012-11-15T13:21:12.263 回答