Подтвердить что ты не робот

Как избежать создания новой строки, если такая же строка существует?

Мне нужно настроить hibernate, чтобы избежать создания повторяющихся строк (хотя существует строка, она создает новую, и, поскольку установлена ​​только одна поданная, все остальное равно NULL)

Скажем, у меня есть строка, следующая за

id des    index age
1  MyName 2     23

Хотя я просто установил MyName как des, и он уже существует в спящем режиме таблицы имен создайте новую строку следующим образом

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

Когда я хочу  , Поэтому я добавил в мой класс следующую аннотацию, но она пересекла Entity и dynamicUpdate.

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

Я использовал @DynamicUpdate, хотя спящий режим принимает его, но все же у меня такая же проблема.

Есть ли другой способ сделать это? Версия моего спящего режима выглядит следующим образом:

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

* Основываясь на комментариях Ray, назначая значение Id дочернего класса, он работает правильно, но как насчет того, если у меня нет идентификатора? мне нужно сделать выбор, чтобы сначала найти идентификатор? Есть ли способ заставить hibernate делать это автоматически r на основе значений дочернего класса rahter, чем отдельный выбор, чтобы найти идентификатор? *

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();
}
4b9b3361

Ответ 1

хотя существует строка, она создает новый

Это не совсем правильно. Это не просто спящий режим, автоматически определяющий создание нового пользователя. Hibernate делает то, что говорит ваш код:

  • В addMyUsers() вы создаете new Name() и new User(), и вы не даете ни одному из них уже существующий идентификатор. Вы сделали эти объекты похожими на новые, а не на уже существующие, которые нужно обновить.
  • В addMyUser() вы вызываете session.merge(user). Hibernate видит, что объекты не имеют идентификатора, поэтому он объединяет их и присваивает им статус NEW. Когда транзакция сбрасывается и выполняется, hibernate генерирует SQL для создания новых идентификаторов и хранения объектов в качестве новых записей.

Если вы хотите определить, существует ли объект уже существующий, и, когда это возможно, работать с предыдущей записью:

  • Получите поля, которые вы хотите использовать (например, из веб-формы) - в вашем случае это включает в себя поле "det".
  • Посмотрите, существует ли запись в базе данных. Извлеките объект, используя спящий режим, через session.find() или session.get(), в вашем случае, используя поле "det".
  • Если объект не найден, создайте новый объект.
  • Для извлеченных объектов вы можете дополнительно отсоединить объект от сеанса до его модификации (например, через session.clear()). Новые созданные объекты уже находятся в отключенном состоянии.
  • Измените объект (установите его поля).
  • Если объект отсоединен, присоедините его через session.merge(). Слияние выполняется как для ранее существовавших отдельных объектов (полученных путем извлечения), так и для новых отдельных объектов (через new <Object>()). В качестве альтернативы для ранее существовавших отдельных объектов вы можете вызвать session.update(), а для новых удаленных объектов вы можете вызвать session.save()/persist().
  • выполнить флеш/зафиксировать транзакцию.

Вам не хватает (2).

Ответ 2

Его основной ключ, который играет здесь важную роль. вы должны использовать имя в качестве первичного ключа в этом случае, но я не буду предлагать вам это сделать, возьмите id в качестве первичного ключа.

Update:

Также в случае обновления идентификатор должен совпадать с записью, которую вы хотите обновить, но в случае вставки идентификатор должен быть нулевым, и вы получите его вставленным в db.

Ответьте на ваши комментарии:

вам нужно получить первичный ключ и отслеживать его следующим образом:

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

Ответ 3

вы должны сначала получить Имя, а не новое имя().

поэтому используйте меню "Поиск пользователя" /раскрывающийся список или что-то для пользователя, чтобы выбрать Имя, которое вы хотите, затем вы можете добавить, что Имя - новый пользователь .name

или если вы не хотите сначала искать имя (из тонкого воздуха # lol), вы не должны использовать User.name с типом Имя в первое место, используйте строку. но это более рискованно. и связь не может быть построена таким образом (вы должны запросить еще раз, если хотите получить Имя из Пользователь с именем x).

Ответ 4

Вы настроили этот способ. Пожалуйста, поделитесь ур кодом, если это не так.

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

Ответ 5

Использование saveOrUpdate() не работало для меня в версии 4.3.Final Hibernate.

Записи "сохраняются" независимо от того, задан или действителен "id" (PK). Используйте save() или update() в зависимости от того, является ли запись "постоянной" (id! = Null и т.д.).

Я провел некоторое время, узнавая, так что, надеюсь, кому-то не придется.