我需要配置hibernate以避免创建重复的行,(尽管该行存在它会创建一个新的行,并且由于只设置了一个字段,因此将所有其余字段设置为NULL)
让我说我有一行如下
id des index age
1 MyName 2 23
虽然我只是将MyName设置为des,但它已经存在于Name表hibernate中 创建一个新行,如下所示
id des index age
1 MyName 2 23
2 MyName Null Null << new row with null values will be created
rather than updating the previous one
当我想要sa 。 所以我在我的课程中添加了以下注释,但是它越过了Entity和dynamicUpdate。
@org.hibernate.annotations.Entity(
dynamicUpdate = true
)
我也使用了@DynamicUpdate
,虽然hibernate接受了它,但我仍然遇到同样的问题。
还有其他方法吗?我的hibernate版本如下:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.1.Final</version>
<type>jar</type>
</dependency>
* 基于Ray的评论自爆,通过为子类的Id分配值,它可以正常工作,但如果我没有ID怎么办?我必须先做一个选择才能找到id吗?是否有任何方法强制hibernate基于child class rahter的值自动执行r而不是单独选择查找id? *
User.Java
....
import org.hibernate.annotations.DynamicUpdate;
@Entity
@Table(name = "user")
@DynamicUpdate
public class User implements Serializable {
private int ID;
private Name name;
private String type;
public User() {
}
@Id
@GeneratedValue
@Column(name = "id")
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
@ManyToOne(cascade = CascadeType.ALL)
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
.....
Name.Java
@Entity()
@Table(name = "Name")
public class Name implements Serializable {
private int id;
private String des;
private String index;
private String age;
public Name() {
}
@Id
@GeneratedValue
@Column(name="id", unique= true, nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
.....
Model.java
public void addMyUsers(){
Name name = new Name();
name.setDes("MyName");
While( ..... )
{
User user = new User();
user.setName(name);
user.setType(X);
addUser(user);
}
}
public void addUser(User user) {
session = Util.getSession();
session.beginTransaction();
session.merge(user);
//session.saveOrUpdate(user);
session.getTransaction().commit();
session.close();
}
答案 0 :(得分:7)
虽然该行存在,但它会创建一个新的
那不太对劲。它不仅仅是休眠自动决定创建一个新用户。 Hibernate正在执行代码告诉它的内容:
addMyUsers()
中,您创建了new Name()
和new User()
,并且您不会为这些都提供预先存在的ID。您已使这些对象看起来像新对象,而不是预先存在的对象需要更新。addMyUser()
,您致电session.merge(user)
。 Hibernate看到对象没有ID - 所以它合并它们并为它们分配NEW状态。当交易被刷新时&amp;已提交,hibernate生成SQL以创建新ID并将对象存储为新记录。如果您想确定某个对象是否已预先存在,并尽可能对之前的记录进行操作:
session.find()
或session.get()
使用休眠来检索对象。 session.clear()
)。新创建的对象已处于分离状态。 session.merge()
附加。合并适用于预先存在的分离对象(通过检索获得)和新的分离对象(通过new <Object>()
)。或者,对于预先存在的分离对象,您可以调用session.update()
,对于新的分离对象,您可以调用session.save()/persist()
。 你错过了(2)。
答案 1 :(得分:4)
它的主键在这里发挥着重要作用。在这种情况下你应该使用name作为主键,但我不建议你这样做,把id作为主键。
更新
同样在更新的情况下,id应该与您要更新的记录相同,但是在插入的情况下,id应为null,您将把它插入db。
回答你的意见:
您需要获取主键并以这种方式跟踪它:
session.update(recordEntity);// or save
int id=recordEntity.getId();
答案 2 :(得分:2)
您必须先获取名称,而不是新名称()。
因此,请使用“搜索用户”/下拉菜单或其他内容供用户选择他们想要的名称,然后您可以将名称添加到新用户.NAME 强>
或者如果您不想首先搜索名称(来自稀薄的空气#lol),则不应在用户名中使用名称类型首先,使用字符串然后。但它风险更大。并且这种关系不能以这种方式构建(如果你想从名字为x的用户获得名称,你必须再次查询。)
答案 3 :(得分:0)
你有这样的配置吗?如果不是这样,请分享您的代码。
@Entity
@Table(name = "example", catalog = "example_catalog")
@org.hibernate.annotations.Entity(
dynamicUpdate = true
)