【问题标题】:How to avoid creating a new row if similar row exists?如果存在类似的行,如何避免创建新行?
【发布时间】:2013-06-09 11:20:14
【问题描述】:

我需要配置休眠以避免创建重复的行,(尽管该行存在它会创建一个新行,并且由于只设置了一个字段,因此将其余所有设置为 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

当我想 . 所以我在我的类中添加了以下注释,但它跨越了实体和动态更新。

@org.hibernate.annotations.Entity(
  dynamicUpdate = true
)

我也用过@DynamicUpdate,虽然hibernate接受了,但我还是有同样的问题。

还有其他方法吗?我的休眠版本如下

<dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>4.2.1.Final</version>
      <type>jar</type>
</dependency>

*根据 Ray 的评论,通过为子类的 Id 分配一个值,它可以正常工作,但是如果我没有 ID 怎么办?我必须先进行选择才能找到 id 吗?有没有什么方法可以强制休眠根据子类的值自动执行它而不是单独选择来查找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();
}

【问题讨论】:

  • 在 4.2.1 上它正在工作,如果可能的话升级到最新版本。
  • @AleksandrM 所以这实际上是重复的。
  • @yair 该问题的答案是错误的,因为这些标签未被弃用。由于没有人能够查看该问题,我正在提出一个新问题

标签: hibernate jakarta-ee hibernate-mapping updates hibernate-annotations


【解决方案1】:

虽然该行存在,但它会创建一个新行

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

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

如果要判断一个对象是否已经存在,并尽可能对之前的记录进行操作:

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

你错过了 (2)。

【讨论】:

  • NP。我已经回答了你大胆的部分。你不能凭空获得身份证。您必须检索它(第 2 步)。
  • @GlenBest 感谢您的回答,但我在stackoverflow.com/questions/17396586/… 遇到了另一个问题
【解决方案2】:

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

更新:

另外,如果更新 id 应该与您要更新的记录相同,但在插入的情况下,id 应该为 null,您将把它插入到 db 中。

回答你的cmets:

您需要获取主键并以这种方式对其进行跟踪:

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

【讨论】:

    【解决方案3】:

    您必须首先获得 Name,而不是 new Name()

    所以使用“搜索用户”/下拉菜单之类的菜单让用户选择他们想要的名称,然后您可以将该名称添加到新用户.name

    或者,如果您不想先搜索名称(凭空而来#lol),则不应使用 User.nameName首先,使用 string 然后。但它的风险更大。并且无法以这种方式建立关系(如果要从具有名称 x 的 User 获取 Name,则必须再次查询)。

    【讨论】:

      【解决方案4】:

      你有没有这样配置过。如果不是这样,请分享您的代码。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-29
        • 1970-01-01
        • 1970-01-01
        • 2012-05-09
        • 2021-07-08
        • 2020-07-14
        • 2015-01-19
        相关资源
        最近更新 更多