Hi,
I'm starting with hibernate, testing it in a J2SE environment.
These are some very basic questions, I'm reading the documentation at the same time, still probably the explanation is somewhere on the documentation, in a more advanced chapter. Since I'm testing/trying as I'm reading it, I'm asking some help on understanding a bit more.
During some basic testing, I'm struggling to find and understand a specific problem:
Code:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.hibernate.model.Company#1]
Database is MySQL, with following definitions:
Code:
create table COMPANY
(
ID bigint not null,
DESCRIPTION char(200) not null,
primary key (ID)
) ENGINE=INNODB;
insert into company(id, description) values(1, 'Company One');
insert into company(id, description) values(2, 'Second Company');
Now the java code "problems" I found:
1# Persisting an existing record:
Code:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my_factory");
EntityManager em = emf.createEntityManager();
Company company = em.find(Company.class, new Long(1));
logger.info("Company [{};{}]", new Object[] { company.getId(), company.getDescription() });
for( Employee employee : company.getEmployees() ) {
logger.info("Employee [{};{};{}]", new Object[] { employee.getId(), employee.getName(), employee.getGenre().getDescription() });
}
Company newCompany = new Company();
newCompany.setId(1);
newCompany.setDescription("New Company");
em.persist(newCompany);
em.close();
emf.close();
In this case I get the following exception:
Code:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.hibernate.model.Company#1]
javax.persistence.PersistenceException: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.hibernate.model.Company#1]
This just confuses me ... shouldn't I be getting an error related with duplicate index on database?
Now if I change this line of code to:
Code:
newCompany.setId(2);
I get no more errors, still it doesn't store anything in the database ... and it couldn't do it anyway, as the index already exists. I was hopping to get an exception here, still nothing happens ...
So I believe it didn't create any transaction? And no storage to the database? Shouldn't the transaction be automatically created, with autocommit=true or something like that?
2# Working with explicit transaction:
Code:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my_factory");
EntityManager em = emf.createEntityManager();
Company company = em.find(Company.class, new Long(1));
logger.info("Company [{};{}]", new Object[] { company.getId(), company.getDescription() });
for( Employee employee : company.getEmployees() ) {
logger.info("Employee [{};{};{}]", new Object[] { employee.getId(), employee.getName(), employee.getGenre().getDescription() });
}
em.getTransaction().begin();
Company newCompany = new Company();
newCompany.setId(1);
newCompany.setDescription("New Company");
em.persist(newCompany);
em.getTransaction().commit();
em.close();
emf.close();
Now I'm getting the same error as before:
Code:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.hibernate.model.Company#1]
javax.persistence.PersistenceException: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.hibernate.model.Company#1]
Now if I change this line of code (again) to:
Code:
newCompany.setId(2);
I get the error:
Code:
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
...
Caused by: java.sql.BatchUpdateException: Duplicate entry '2' for key 'PRIMARY'
Hurray! That was the kind of error I was expecting, in every code execution I run ...
Can anyone explain this behavior to me?
Is the begin/commit instructions always required? Shouldn't hibernate manage it by itself as default (probably there is a setting, although I prefer to explicitly declare transaction boundaries)?
Can anyone explain that "org.hibernate.NonUniqueObjectException" error? I've read ID=1 object, then I create and try to persist an object with ID=1. Okay, so it should give me an error, but I was expecting the error to be like a "duplicate primary key" error exception ... does it mean hibernate caches objects to the point of checking before trying persisting them?
Thanks