I have a very strange LazyIntializationException. We are using hibernate 3.2.5.ga and JPA and MySQL.
Here is my mapping xml.
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" version="1.0">
<persistence-unit-metadata>
</persistence-unit-metadata>
<entity name="ClassA" class="hibernatetestapp.ClassA">
<table name="class_a"/>
<attributes>
<id name="classAId">
<column name="ClassA_Id"/>
<generated-value strategy="IDENTITY"/>
</id>
<basic name="classAValue">
<column name="ClassA_Value"/>
</basic>
<one-to-many name="classBCollection" fetch="EAGER">
<join-column name="ClassA_Ref" referenced-column-name="ClassA_Id"/>
<cascade>
<cascade-all/>
</cascade>
</one-to-many>
</attributes>
</entity>
<entity name="ClassB" class="hibernatetestapp.ClassB" metadata-complete="true">
<table name="class_b"/>
<attributes>
<id name="classBId">
<column name="ClassB_Id"/>
<generated-value strategy="IDENTITY"/>
</id>
<basic name="classBValue" optional="false">
<column name="ClassB_Value"/>
</basic>
</attributes>
</entity>
</entity-mappings>
my persistance.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="HibernateTestAppPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<class>hibernatetestapp.ClassA</class>
<class>hibernatetestapp.ClassB</class>
<properties>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.password" value="admin"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/HibernateTest"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
</properties>
</persistence-unit>
</persistence>
and my sql for creating database
Code:
--
-- Table structure for table `class_a`
--
DROP TABLE IF EXISTS `class_a`;
CREATE TABLE `class_a` (
`ClassA_Id` int(10) unsigned NOT NULL auto_increment,
`ClassA_Value` varchar(45) NOT NULL,
PRIMARY KEY (`ClassA_Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `class_a`
--
/*!40000 ALTER TABLE `class_a` DISABLE KEYS */;
LOCK TABLES `class_a` WRITE;
UNLOCK TABLES;
/*!40000 ALTER TABLE `class_a` ENABLE KEYS */;
--
-- Table structure for table `class_b`
--
DROP TABLE IF EXISTS `class_b`;
CREATE TABLE `class_b` (
`ClassB_Id` int(10) unsigned NOT NULL auto_increment,
`ClassB_Value` varchar(45) default NULL,
`ClassA_Ref` int(10) unsigned default NULL,
PRIMARY KEY (`ClassB_Id`),
KEY `FK_Class_B_1` (`ClassA_Ref`),
CONSTRAINT `FK_Class_B_1` FOREIGN KEY (`ClassA_Ref`) REFERENCES `class_a` (`ClassA_Id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `class_b`
--
SET FOREIGN_KEY_CHECKS=1;
my test classes
ClassA
Code:
package hibernatetestapp;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Id;
/**
*
* @author kiril.kalchev
*/
public class ClassA implements Serializable {
private static final long serialVersionUID = 1L;
//@Id
private Integer classAId;
private String classAValue;
private Set<ClassB> classBCollection;
public ClassA() {
this(null, null);
}
public ClassA(Integer classAId) {
this(classAId, null);
}
public ClassA(Integer classAId, String classAValue) {
this.classAId = classAId;
this.classAValue = classAValue;
classBCollection = new HashSet<ClassB>();
}
public Integer getClassAId() {
return classAId;
}
public void setClassAId(Integer classAId) {
this.classAId = classAId;
}
public String getClassAValue() {
return classAValue;
}
public void setClassAValue(String classAValue) {
this.classAValue = classAValue;
}
public Set<ClassB> getClassBCollection() {
return classBCollection;
}
public void setClassBCollection(Set<ClassB> classBCollection) {
this.classBCollection = new HashSet<ClassB>(classBCollection);
}
@Override
public String toString() {
return "hibernatetestapp.ClassA[classAId=" + classAId + "]";
}
}
ClassB
Code:
package hibernatetestapp;
import java.io.Serializable;
/**
*
* @author kiril.kalchev
*/
public class ClassB implements Serializable {
private static final long serialVersionUID = 1L;
private Integer classBId;
private String classBValue;
public ClassB() {
}
public ClassB(Integer classBId) {
this.classBId = classBId;
}
public ClassB(Integer classBId, String classBValue) {
this.classBId = classBId;
this.classBValue = classBValue;
}
public Integer getClassBId() {
return classBId;
}
public void setClassBId(Integer classBId) {
this.classBId = classBId;
}
public String getClassBValue() {
return classBValue;
}
public void setClassBValue(String classBValue) {
this.classBValue = classBValue;
}
@Override
public String toString() {
return "hibernatetestapp.ClassB[classBId=" + classBId + "]";
}
}
and my main test class
Code:
package hibernatetestapp;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
*
* @author kiril.kalchev
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
ClassB b1 = new ClassB(null, "B1");
ClassB b2 = new ClassB(null, "B2");
ClassA a1 = new ClassA(null, "A1");
a1.getClassBCollection().add(b2);
a1.getClassBCollection().add(b1);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("HibernateTestAppPU");
ClassA attached = persistObject(emf, a1);
ClassA getted = getClassAObject(emf, attached);
System.out.println(getted.getClassBCollection());
}
private static ClassA getClassAObject(EntityManagerFactory emf, ClassA attached) {
EntityManager em = emf.createEntityManager();
ClassA getted = em.find(ClassA.class, attached.getClassAId());
em.close();
return getted;
}
private static ClassA persistObject(EntityManagerFactory emf, ClassA a1) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(a1);
em.getTransaction().commit();
em.close();
return a1;
}
}
If I remove the comment from @Id annotation in ClassA, everything works fine. Also if I use only one Entity Manager which we open at the beginning of my main method and close the manager at the end of the method everything is OK.
I can't use one entity manager in my real project. Does anyone have an idea what happen if we have @Id annotation?
Thanks, Kiril