Reputation: 113
In my database table Attribute, I will have a list of data loaded first. Every time, when I want to persist a new record of MyAttribute, I will need to search through the table Attribute first and select the appropriate record from table Attribute before I insert to table MyAttribute.
@Entity
class MyAttribute{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@ManyToOne(targetEntity = Attribute.class)
@JoinColumn(name="attribute_id", referencedColumnName="id")
Attribute detail;
private String greet;
public MyAttribute(){
this.greet = "Hello World.";
this.detail = new MyDbLayer().selectAttributeDetail("first"); //Error is thrown here.
}
//getter & setter
}
@Entity
class Attribute{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Index(name = "name_index")
@Column(unique=true )
private String name;
//getter & setter
}
class MyDbLayer{
private EntityManagerFactory emf;
public MyDbLayer() {
emf = Persistence.createEntityManagerFactory("MyPu");
}
public Attribute selectAttributeDetail(String name) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Query queryGetAttribute = em.createQuery("select a from Attribute a where a.name = :attributeName");
List<AttributeDescription> attributeDescList = queryGetAttribute.setParameter("attributeName", name).getResultList();
AttributeDescription tempAttribute = null;
if (!attributeDescList.isEmpty()) {
tempAttribute = (AttributeDescription) attributeDescList.get(0);
}
em.clear();
em.close();
return tempAttribute;
}
}
I'm not sure why I keep on receiving error like:
javax.persistence.PersistenceException: [PersistenceUnit: MyPu] Unable to build EntityManagerFactory
Caused by: org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
Caused by: org.hibernate.InstantiationException: could not instantiate test object
P.S. This is not the real code that I'm working on, but the structure is more or less the same.
Upvotes: 0
Views: 1580
Reputation: 693
It is not in the JPA model to be able to access an EntityManager
from an Entity. It can be done, but it can have different behaviors depending on the implementation.
In your case accessing an EntityManager
from the no args constructor is never a good idea. Because thats the constructor used by the EntityManager
when it loads an Entity. So every time MyAttribute
is loaded by an EntityManager
you will try to create antoher EntityManager
to initialise the detail
relationship which will be overwritten by the first EntityManager
using the value it loaded from the database.
Usually you should have a service layer which has access to an EntityManager
that manages your JPA Entities.
Upvotes: 0
Reputation: 2025
What about making a second construtor for MyAttribute?
public MyAttribute(){
this.greet = "Hello World.";
// this.detail = new MyDbLayer().selectAttributeDetail("first"); //Error is thrown here.
}
public MyAttribute(Attribute detail){
this.greet = "Hello World.";
this.detail = detail;
}
The default constructor is also used by jpa to load persited objects. this can cause unexpected behaviour
Upvotes: 3