Каскад гибернации «многие ко многим» создает дубликаты в дочерней ссылке

Итак, я новичок в спящем режиме. Вопрос касается каскадирования многие ко многим, избегая добавления повторяющихся значений. Поэтому я следую этому примеру. сопоставление многих ко многим в режиме гибернации Tutorialspoint

Проблема в том, что если я запускаю программу дважды, она добавляет повторяющиеся значения в таблицу certificate.

После того, как я вставляю значения в таблицу сотрудников. Он каскадирует и вставляет значения в таблицу certificate:

id certificate_name
1   PMP
2   MBA
3   MCA

После того, как я запустил этот пример во второй раз, он выполняет те же действия.

id certificate_name
1   PMP
2   MBA
3   MCA
4   PMP
5   MBA
6   MCA

Но тогда таблица сертификатов имеет повторяющиеся значения. Значения 4-6 такие же, как 1-3.

Я попытался добавить уникальное ограничение на сертификат таблицы, но затем получаю эту ошибку:

ОШИБКА: повторяющаяся запись «PMP» для ключа «certificate_name_UNIQUE»

Как я могу вставить значения, чтобы не дублировать их. Можно ли этого избежать, или мне нужно использовать другие методы, чтобы сделать это.

Также добавьте pom.xml, если необходимо использовать банки.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>testHibernateCascade2</groupId>
  <artifactId>testHibernateCascade2</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.3.6.Final</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.31</version>
    </dependency>
  </dependencies>  

</project>

person K.I.    schedule 23.09.2014    source источник
comment
Нужны дополнительные сведения, добавьте сведения об объекте и код, как вы сохраняете объекты.   -  person Chaitanya    schedule 23.09.2014
comment
Если вы используете методы, похожие на те, что в примере, то правильно, что он добавляет что-то снова, если вы запустите его снова. Нет проверки на дубликаты. Я думаю, вы могли бы добавить измененный listEmployees (с параметрами поиска) и проверить, существует ли уже сотрудник.   -  person Feroc    schedule 23.09.2014
comment
Здесь больше проблем, чем вы думаете; в примере используется набор, который уже должен предотвращать дублирование еще до того, как он попадет в базу данных... если методы equals и hashcode для сущностей реализованы правильно.   -  person Gimby    schedule 23.09.2014
comment
Перед вставкой любого certificate_name проверьте, присутствует ли он уже в таблице. Добавление unique constarint вызовет ошибку, если будет вставлен повторяющийся элемент.   -  person Rohan    schedule 23.09.2014
comment
Это было адресовано Feroc. Проблема не в сотрудниках, а в таблице сертификатов при использовании каскада. Если добавление значений в сертификат автоматизировано, следует ли проверять значения на дублирование?   -  person K.I.    schedule 23.09.2014


Ответы (1)


Хорошо, я нашел решение. Сначала я проверяю, существует ли такой сертификат в БД, используя HQL и критерии.

public int getID(String certificateName){

    Criteria cr = session.createCriteria(Certificate.class);
    cr.add(Restrictions.eq("certificate", certificateName));
    List<?> results = cr.list();
    if (results.isEmpty()){ 
        return -1;}
        else{
            Iterator<?> iterator = results.iterator();
            Certificate certificate = (Certificate) iterator.next();
            return certificate.getId();
        }
}

Во-вторых, если имя_сертификата отсутствует в таблице certificate, я создаю новый объект, иначе добавляю существующий.

    ...
    String [] userCertificates = {"BKA","RRA","DMA"};

    HashSet<Certificate> certificatesSet = new HashSet<Certificate>();

    for (int i = 0; i<userCertificates.length;i++){
        int id = getID(userCertificates[i]);
        if (id == -1){
            certificatesSet.add(new Certificate(userCertificates[i]));
        }
        else{
            certificatesSet.add((Certificate) cs.getObject(Certificate.class, id));
        }
    }
    ...

И это сработало очень хорошо.

person K.I.    schedule 24.09.2014