@Unique member combination not working

#1

Why does the below code not enforce unique restrictions?
 

Person

	@Entity
	@Unique(members = {"name", "surname"})
	public class Person implements Serializable {
	    @Id
	    @GeneratedValue
	    private Integer id;
	    private String name;
	    private String surname;

	public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

	public String getName() {
	        return name;
	    }
	    public void setName(String name) {
	        this.name = name;
	    }

	

	public String getSurname() {
	        return surname;
	    }
	    public void setSurame(String surname) {
	        this.surname= surname;
	    }
}

PersonDao

public class PersonDao {

    public void create(Person person, ServletContext servletContext) {
        EntityManagerFactory emf = (EntityManagerFactory) servletContext.getAttribute("emf");
        EntityManager em = emf.createEntityManager();
        try {
            em.getTransaction().begin();
            em.persist(person);
            em.getTransaction().commit();
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            em.close();
        }
    }
}

Main

public static void main(String[] args) {
    Person p1 = new Person("John", "Doe");
    Person p2 = new Person("John", "Doe");
    Person p3 = new Person("John", "Doe");
    PersonDao personDao = new PersonDao();
    personDao.create(p1);
    personDao.create(p2);
    personDao.create(p3);
}
#2

Tried your example, with required adjustments to make it runnable:

import java.io.*;

import javax.jdo.annotations.*;
import javax.persistence.*;


public final class T1522
{
    static EntityManagerFactory emf =
        Persistence.createEntityManagerFactory(
            "objectdb:$objectdb/db/test.tmp;drop");

    public static void main(String[] args) {

        Person p1 = new Person("John", "Doe");
        Person p2 = new Person("John", "Doe");
        Person p3 = new Person("John", "Doe");
        PersonDao personDao = new PersonDao();
        personDao.create(p1);
        personDao.create(p2);
        personDao.create(p3);
    }

    public static class PersonDao {
        public void create(Person person) {
            EntityManager em = emf.createEntityManager();
            try {
                em.getTransaction().begin();
                em.persist(person);
                em.getTransaction().commit();
            } finally {
                if (em.getTransaction().isActive()) {
                    em.getTransaction().rollback();
                }
                em.close();
            }
        }
    }

    @Entity
    @Unique(members = {"name", "surname"})
    public static class Person implements Serializable {
        @Id @GeneratedValue private Integer id;
        private String name;
        private String surname;

        public Person(String name, String surname)
        {
            this.name = name;
            this.surname = surname;
        }
    }
}

The output, as expected, is:

Exception in thread "main" [ObjectDB 2.x] javax.persistence.RollbackException
Failed to commit transaction: Unique constraint (com.objectdb.test.bug.forum.T1522$Person[name,surname]) failed: Attempt to reuse an existing value (('John','Doe')) (error 613)
at com.objectdb.jpa.EMImpl.commit(EMImpl.java:302)
at com.objectdb.test.bug.forum.T1522$PersonDao.create(T1522.java:33)
at com.objectdb.test.bug.forum.T1522.main(T1522.java:22)
Caused by: javax.persistence.PersistenceException: com.objectdb.error.UserException: Unique constraint (com.objectdb.test.bug.forum.T1522$Person[name,surname]) failed: Attempt to reuse an existing value (('John','Doe'))
at com.objectdb.error.jpa._PersistenceException.construct(_PersistenceException.java:47)
at com.objectdb.error.jpa.JpaErrorManager.buildAPIUserException(JpaErrorManager.java:145)
at com.objectdb.error.jpa.JpaErrorManager.buildAPIUserException(JpaErrorManager.java:78)
... 5 more
Caused by: com.objectdb.error.UserException: Unique constraint (com.objectdb.test.bug.forum.T1522$Person[name,surname]) failed: Attempt to reuse an existing value (('John','Doe'))
ObjectDB Support
#3

Thanks, it worked. I was using servlet context because I thought that using static variables in a multi-threaded environment would be too risky, however, I have updated my code to just use a static EntityManagerFactory so I don't think it should be too much of a problem.

#4

It should work the same as with keeping the EntityManagerFactory in the servlet context.

Maybe you had an old EntityManagerFactory in the servlet context without the Unique?

Notice that adding Unique to an existing database is like adding an index (since Unique is implemented as an index), and therefore requires index rebuilding (currently using the ObjectDB Doctor).

ObjectDB Support

Reply