Reputation: 8015
I am new to hibernate and I am trying to implement one-to-many relationship with cascade loading and updating. However, my code always generates org.apache.jasper.JasperException: org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
exception. Could you take a look on my attempt and suggest what am I doing wrong?
The general idea is that there is a Company class which contains set of customers. When creating new instance of customer, I add him to a company and persist everything.
Entities (only displaying relevant parts, or at least I hope so)
public class Company implements Serializable {
private static final long serialVersionUID = 146243652;
private String id;
private String name;
private String website;
private Set<Customer> customers;
... getters, setters etc
public class Customer implements Serializable {
private static final long serialVersionUID = 864235654;
private String name;
private String surname;
private String adress;
private String id;
private Company company;
customer.hbm.xml:
<hibernate-mapping>
<class name="wa2.entities.Customer" table="CUSTOMER">
<id column="ID" name="id" type="java.lang.String" />
<property column="NAME" name="name" type="java.lang.String" />
<property column="SURNAME" name="surname" type="java.lang.String" />
<property column="ADRESS" name="adress" type="java.lang.String" />
<many-to-one name="COMPANY" class="wa2.entities.Company">
<column name="COMPANY_ID" not-null="true"></column>
</many-to-one>
</class>
</hibernate-mapping>
company.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="wa2.entities.Company" table="COMPANY">
<id column="ID" name="id" type="java.lang.String" />
<property column="NAME" name="name" type="java.lang.String" />
<property column="WEBSITE" name="website" type="java.lang.String" />
<set name="CUSTOMERS" table="CUSTOMER" fetch="select">
<key>
<column name="CUSTOMER_ID" not-null="true"></column>
</key>
<one-to-many class="wa2.entities.Customer"/>
</set>
</class>
</hibernate-mapping>
Saving customer (this worked before the implementation of one-to-many relationship so I doubt that there is anything wrong with this code):
Customer customer = new Customer();
String name = req.getParameter("name");
customer.setName(name);
String surname = req.getParameter("surname");
customer.setSurname(surname);
String adress = req.getParameter("adress");
customer.setAdress(adress);
String companyID = req.getParameter("companyId");
Company company = repository.loadCompany(companyID);
customer.setCompany(company);
String id = UUID.randomUUID().toString();
customer.setId(id);
repository.saveCustomer(customer);
I hope that I did not forget any relevant part. If so, please tell me and I will post the relevant code. Thank you very much for any help!
EDIT:
Thanks for the responses. It seems that I wrote the names wrongly in capitals. I changed that and now I am getting failed to lazily initialize a collection of role: wa2.entities.Company.customers, could not initialize proxy - no Session
Upvotes: 0
Views: 380
Reputation: 584
since this is an mapping exception, i guess it comes up during session factory creation, and not when saving? also, seeing the whole stacktrace could help. your exception can be caused by a mismatch of property names between mapping file and beans. see Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister.
in your code you have the name attribute values in
<many-to-one name="COMPANY" class="wa2.entities.Company">
<column name="COMPANY_ID" not-null="true"></column>
</many-to-one>
and
<set name="CUSTOMERS" table="CUSTOMER" fetch="select">
<key>
<column name="CUSTOMER_ID" not-null="true"></column>
</key>
<one-to-many class="wa2.entities.Customer"/>
</set>
in uppercase, while the properties in your pojos are named company and customer.
Upvotes: 3
Reputation: 4602
One principle in hibernate, that is often stated, but even more often overseen, is, that you need to keep a clean object tree, or the database will not be kept in sync properly.
I think this causes your problem: You need to keep the tree clean. But you don't: You add the customer to the company on the customer side, but you do not add the customer to the company's customer set.
In your code, you have added a vice-versa link between customer and company. I would add an inverse to the link, for this is what you want.
Second: If you start with hibernate now, really think about the annotation approach. If you inherit legacy apps, stay with the XML, but if you start out fresh ...
Upvotes: 0