如果存在类似的行,如何避免创建新行



我需要配置hibernate以避免创建重复的行(尽管行存在,但它会创建一个新行,并且由于只设置了一个文件,因此将所有其他文件设置为NULL)

假设我有一行如下

id des    index age
1  MyName 2     23

虽然我刚刚设置MyName为des,它已经存在于名称表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

当我想说.所以我添加了下面的注释到我的类,但它越过实体,和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>

*基于雷的评论吹了,通过分配一个值给子类的Id,它工作正常,但如果我没有Id怎么办?我必须先做一个选择来找到id吗?是否有任何方法可以强制hibernate根据子类的值自动执行,而不是单独选择来查找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();
}

尽管行已经存在,但它会创建一个新的

那不太对。它不仅仅是hibernate自动决定创建一个新用户。Hibernate正在做代码告诉它的事情:

  • addMyUsers()中,您创建new Name()new User(),并且您不给它们提供预先存在的ID。您已经使这些对象看起来像新对象,而不是要更新的已有对象。
  • addMyUser()中,调用session.merge(user)。Hibernate看到对象没有ID——所以它合并它们并为它们分配NEW状态。当事务被刷新时&提交后,hibernate生成SQL来创建新id并将对象存储为新记录。

如果您想确定一个对象是否存在,并在可能的情况下对前一个记录进行操作:

  1. 获取您想要使用的字段(例如,从web表单)-在您的情况下,这包括"det"字段。
  2. 查看数据库中是否已经存在该记录。通过session.find()session.get()使用hibernate检索对象,在本例中使用"det"字段。
  3. 如果找不到对象,然后创建一个新对象。
  4. 对于检索对象,您可以选择在修改之前将对象从会话中分离出来(例如通过session.clear())。新创建的对象已经处于分离状态。
  5. 修改对象(设置其字段)。
  6. 如果对象被分离,则通过session.merge()附加。合并适用于已经存在的分离对象(通过检索获得)和新的分离对象(通过new <Object>())。另外,对于已经存在的分离对象,可以调用session.update(),对于新的分离对象,可以调用session.save()/persist()
  7. 刷新/提交事务。

你错过了(2).

这里起重要作用的主键。在这种情况下,您应该使用name作为主键,但我不建议您这样做,使用id作为主键。

更新:

同样在情况下,更新id应该与你想要更新的记录相同,但在插入的情况下,id应该是空的,你会得到它插入到db。

回复你的评论:

你需要获取主键并以这种方式跟踪它:

   session.update(recordEntity);// or save 
   int id=recordEntity.getId();

必须先获取Name,而不是new Name()

所以使用菜单,如"搜索用户"/下拉菜单或用户选择他们想要的名称,然后你可以将名称添加到new user . Name

或者如果你不想首先搜索Name(从空气#lol),你不应该首先使用User.name类型的Name,然后使用string。但风险更大。如果您想从用户中获得名称为x的Name,则必须再次查询。

您已经这样配置了吗?如果不是这样,请分享你的代码。

@Entity
@Table(name = "example", catalog = "example_catalog")
@org.hibernate.annotations.Entity(
        dynamicUpdate = true
)

相关内容

  • 没有找到相关文章

最新更新