休眠Session.save是否尝试保存“所有”瞬态实体?

时间:2014-02-02 15:49:22

标签: java hibernate session save transient

我有一个具有主键和唯一约束的实体,如下所示

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

@Id
@GeneratedValue
@Column(name = "ID", nullable = false)
private Integer id;

@Column(name = "NAME")
private String name;

@Column(name = "USER_ID", unique = true, nullable = false)
private String userId;

@Column(name = "PASSWORD")
private String password;

public Employee() {
    this("", "", "");
}

public Employee(String name, String userId, String password) {
    this(null, name, userId, password);
}

public Employee(Integer id, String name, String userId, String password) {
    if (id != null)
        this.id = id;
    this.name = name;
    this.userId = userId;
    this.password = password;
}
}
  1. 在我的单元测试代码的各个地方,我调用了我的新员工(...),我不会坚持这些对象。
  2. 在几个这样的实例之后,我第一次尝试执行session.save(new Employee()),它在USER_ID上给出了一个带有Id值大于1的ConstraintViolationException。相反,如果我尝试持久化(session) .save(新员工(“”,“userID”,“”))工作正常。
  3. 现在我确信堆中有Employee类的对象,这些对象是瞬态的(据我所知)。问题是session.save会尝试保存所有这些对象。

    如果是 - 我应该怎么做才能避免保存所有实例。

    如果不是 - 任何人都可以告诉我为什么会收到ConstraintViolationException。

    PS:在异常之后,数据库中没有数据出现(甚至不是单个实体),因此我怀疑save方法可能正在对瞬态对象做某事并且不提交它。我已经尝试过设置autocommit = true而且也没有运气。

2 个答案:

答案 0 :(得分:0)

如果永远不会通过保存,合并等方式将会话传递给会话,则会话不知道使用new Employee(...)创建的对象

这意味着在第一次保存调用之前创建的对象与问题无关。

当调用session.save(new Employee())时,Hibernate将为对象创建一个id,例如通过序列,然后仅在刷新和提交会话时才持久化。

问题似乎是数据库中已经存在一些数据。

答案 1 :(得分:0)

ConstraintViolation可能是由违反UNIQUE约束或NOT NULL约束引起的。我认为这是后者。问题是您将userId设置为空字符串,并且许多数据库(例如Oracle,MySQL)将转换并将空字符串存储为NULL。并且您已将列设置为nullable = false。我不知道h2数据库如何处理空字符串,但是看起来您可以设置数据库兼容模式,因此您可以使用将空字符串视为空的模式。

尝试删除nullable = false(以及数据库中的NOT NULL约束),或者在持久化之前始终将userID设置为某个非null,非空值。