更新时间:2023-02-17 17:32:29
虽然行存在,但它创建了一个新行
这并不完全正确。这不仅仅是休眠自动决定创建一个新用户。 Hibernate正在做你的代码告诉它的内容:
$ b $ ul
addMyUsers()
中,你创建新的名字()
和新的用户()
,并且你既不给这些预先存在的ID。您已使这些对象看起来像新的,而不是预先存在的对象。 addMyUser()
中,您调用 session.merge(user)
。 Hibernate看到这些对象没有ID - 所以它将它合并并赋予它们NEW状态。当交易清空& hibernate生成SQL来创建新的ID并将对象存储为新记录。如果您想确定对象是否为pre - 存在,并在可能的情况下对以前的记录进行操作:
session.find()
或 session.get()
检索对象,在你的情况下使用 det字段。 session.clear()
)修改会话中的对象。新创建的对象已处于分离状态。 session.merge()
进行连接。合并适用于既有的分离对象(通过检索获得)和新的分离对象(通过 new< Object>()
)。或者,对于预先存在的分离对象,您可以调用 session.update()
;对于新的分离对象,您可以调用 session.save()/ persist ()
。 您错过了(2)。 p>
I need to configure hibernate to avoid creating duplicate rows, (although the row exists it creates a new one, and since only one filed is set it set all the rest to NULL)
Lets say I have a row as following
id des index age
1 MyName 2 23
Although I just set MyName as des and it already exists in the Name table hibernate create a new row as following
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
When I want to sa . So I have added the following annotation to my class but it crossed the Entity, and dynamicUpdate.
@org.hibernate.annotations.Entity(
dynamicUpdate = true
)
I used @DynamicUpdate
as well, although hibernate accept it but still I have the same problem.
Is there any other method to do it ? Version of my hibernate is as following
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.1.Final</version>
<type>jar</type>
</dependency>
*Based on Ray's comment blew, By assigning a value to Id of child class it works properly but how about if I do not have the ID? do I have to do a select to find the id first ? Is there any method to force hibernate to do it automatically r based on values of child class rahter than doing a separate select to find the 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();
}
although the row exists it creates a new one
That's not quite right. It's not just hibernate automatically deciding to create a new user. Hibernate is doing what your code tells it to:
addMyUsers()
, you create new Name()
and new User()
, and you give neither of these a pre-existing ID. You have made these objects look like new ones, rather than pre-existing ones to be updated.addMyUser()
, you call session.merge(user)
. Hibernate sees the objects have no ID - so it merges them and assigns them the NEW status. When the transaction is flushed & committed, hibernate generates SQL to create new IDs and store the objects as new records.If you want to determine whether an object is pre-existing, and operate on the previous record where possible:
session.find()
or session.get()
, in your case using the "det" field. session.clear()
). Newly created objects are already in a detached state. session.merge()
. Merge works for both pre-existing detached objects (obtained via retrieval) and new detached objects (via new <Object>()
). Alternatively, for pre-existing detached objects you can call session.update()
and for new detached objects you can call session.save()/persist()
. You're missing (2).