我有一个具有主键和唯一约束的实体,如下所示
@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;
}
}
现在我确信堆中有Employee类的对象,这些对象是瞬态的(据我所知)。问题是session.save会尝试保存所有这些对象。
如果是 - 我应该怎么做才能避免保存所有实例。
如果不是 - 任何人都可以告诉我为什么会收到ConstraintViolationException。
PS:在异常之后,数据库中没有数据出现(甚至不是单个实体),因此我怀疑save方法可能正在对瞬态对象做某事并且不提交它。我已经尝试过设置autocommit = true而且也没有运气。
答案 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,非空值。