Smajl
Smajl

Reputation: 8015

Hibernate one-to-many mapping configuration

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

Answers (2)

Lutz M&#252;ller
Lutz M&#252;ller

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

thst
thst

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

Related Questions