2

Ok so I'm new to hibernate. The question is about cascade many-to-many, avoiding to add duplicate values. So I follow this example. tutorialspoint hibernate many to many mapping

The problem is this, that if I run program twice it adds duplicate values to certificate table.

After I insert values to employee table. It cascades and inserts values to certificate table:

id certificate_name
1   PMP
2   MBA
3   MCA

After I run this example second time it does the same actions.

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

But then certificate table has dublicate values. Values 4-6 are the same as 1-3.

I tried to add unique constraint on table certificate, but then I get this error:

ERROR: Duplicate entry 'PMP' for key 'certificate_name_UNIQUE'

How can I insert values not to duplicate them. Can this be avoided, or do I have to use other techniques to do that.

Also add pom.xml if needed to use jars.

<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>
Petar Butkovic
  • 1,820
  • 15
  • 14
K.I.
  • 759
  • 1
  • 11
  • 30
  • Need more details, add the entity details and the code how you are saving the entities. – Chaitanya Sep 23 '14 at 11:36
  • If you're using methods similar to the ones in the example, then it's correct that it is adding something again if you run it again. There's no check for duplicates. I guess you could add a modified listEmployees (with search parameters) and check if the employee already exists. – Core_F Sep 23 '14 at 11:38
  • There are more problems here than you might think; the example uses a Set which should already prevent duplicity before it ever reaches the database... if the equals and hashcode methods on the entities are properly implemented. – Gimby Sep 23 '14 at 11:42
  • 1
    Before inserting any `certificate_name` check if it is already present in table.Adding `unique` constarint will throw error if duplicate element is inserted. – Rohan Sep 23 '14 at 11:44
  • This was addressed to Feroc.The problems is not about employees the problem is with certificate table when using cascade. If adding values to certificate is automated should it check values for duplication? – K.I. Sep 23 '14 at 11:46

1 Answers1

0

Ok, I found the solution. First I check if such certificate already exists in DB using HQL and Criteria.

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

Second if certificate_name is not in certificate table I create new object, else I add existing.

    ...
    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));
        }
    }
    ...

And that worked very well.

K.I.
  • 759
  • 1
  • 11
  • 30