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


我需要配置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();
}

11456
2018-06-13 06:48


起源

看到 stackoverflow.com/q/8935975/1700321。 - Aleksandr M
@AleksandrM谢谢我在此之前没有给出解决方案,因为这些标签已被弃用。
在4.2.1它正在工作,如果可能升级到最新。 - Snehal Patel
@AleksandrM所以这实际上是重复的。 - yair
@yair这个问题的答案是错误的,因为这些标签不会被弃用。由于没有人能够看到这个问题,我正在提出一个新问题


答案:


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

那不太对劲。它不仅仅是休眠自动决定创建一个新用户。 Hibernate正在执行代码告诉它的内容:

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

如果要确定对象是否已预先存在,请尽可能对先前的记录进行操作:

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

你错过了(2)。


7
2018-06-28 06:50



问题更新请阅读粗体部分谢谢
NP。我已经回答了你的大胆部分。你无法从“稀薄的空气”中获取身份证。您必须检索它(步骤2)。 - Glen Best
@GlenBest感谢您的回答,但我还有另外一个问题 stackoverflow.com/questions/17396586/... - J888


它的主要关键在这里发挥着重要作用。在这种情况下你应该使用name作为主键,但我不建议你这样做,把id作为主键。

更新:

同样在更新的情况下,id应该与您要更新的记录相同,但是在插入的情况下,id应该为null,您将在db中插入它。

回答你的意见:

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

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

4
2018-06-28 07:15





你必须得到 名称 首先,不是 新名字()

所以使用“搜索用户”/下拉菜单等菜单供用户选择 名称 他们想要,然后你可以添加 名称 至 新用户名

或者如果你不想先搜索名字(从稀薄的空气#lol),你不应该使用 用户名 与...的类型 名称 首先,使用  然后。但它风险更大。并且这种关系不能以这种方式构建(如果你想获得,你必须再次查询 名称 来自 用户 名字为x)。


2
2018-06-30 04:56





你有这样的配置吗?如果不是这样,请分享你的代码。

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

0
2018-06-17 11:41



正如我在问题中所提到的,它不起作用
你可以分享代码吗? - Meiyappan Kannappa
问题已更新