while using hibernate,I came across this problem mapping classes in two different packages.
I have a myapp.domain.ItemforSale class which is to be mapped to myapp.cart.CartItem
I created CartItem.hbm.xml as below
<hibernate-mapping package="myapp.cart">
<class name="CartItem" table="CARTITEM">
<id name="cartItem_id" column="CARTITEM_ID" type="long">
<generator class="native"/>
</id>
<property name="quantity" type="int" column="QUANTITY" />
<many-to-one name="itemforsale" class="myapp.domain.ItemforSale" column="ITEM_FORSALE_ID" lazy="false" />
</class>
...
I have a unidirectional mapping from CartItem to ItemForSale entity.While running a test on saving ItemForSale instances to db..I got this error
506 [main] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml
506 [main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml
571 [main] INFO org.hibernate.cfg.Configuration - Reading mappings from resource : myapp/domain/ItemForSale.hbm.xml
636 [main] INFO org.hibernate.cfg.HbmBinder - Mapping class: bookshop.domain.ItemForSale ->ITEMFORSALE
...
746 [main] INFO org.hibernate.cfg.Configuration - Reading mappings from resource : myapp/cart/CartItem.hbm.xml
751 [main] INFO org.hibernate.cfg.HbmBinder - Mapping class: myapp.cart.CartItem -> CARTITEM
...
org.hibernate.MappingException: Association references unmapped class: myapp.domain.CartItem
I removed the package attribute from element and put fully classified class names.Still I get the same exception..
<hibernate-mapping>
<class name="myapp.cart.CartItem" table="CARTITEM">
<id name="cartItem_id" column="CARTITEM_ID" type="long">
<generator class="native"/>
</id>
<property name="quantity" type="int" column="QUANTITY" />
<many-to-one name="itemforsale" class="myapp.domain.ItemForSale" column="ITEM_FORSALE_ID" lazy="false" />
</class>
As a final attempt,I moved the CartItem to myapp.domain package and everything works!
Any idea why this happens?It won't make sense in my app to move myapp.cart.CartItem to myapp.domain ..Any help greatly appreciated.
thanks
mark
org.hibernate.MappingException: Association references unmapped class: myapp.domain.CartItem
This only means it is searching for CartItem on myapp.domain package but your class is actually in myapp.cart package. So basically the hibernate mapping that you have shown is correct, but I think there could be some issues on your java class. Could you please display your java classes related to your issue?
Or you haven't display other related hibernate mapping that could cause this exception.
Also make sure all mappings in hibernate.cfg.xml or Spring's applicationContext corresponds to actual mappings.
Related
I am taking an existing Java application and working on updating it from Hibernate 3 where we used hbm.xml files for Entity Mappings. We are now using Hibernate 5.5.5.Final and the code compiles with ehcache, but now I get an error with the code when starting to run it.
I should start off that one of the Hibernate properties is:
validate
The error message I am getting now is:
org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [my_db_dev.Project_myTemplateInfos]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:121)
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:89)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:200)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:327)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
I would love to completely remove all the hbm.xml files and replace with them with Entity Mapping POJO's with annotations, however, that is not an option right now. The existing application has this different object model that goes throughout, so I don't want to mess with that right now. That will be in the next phase.
According to the error I am missing a table named 'Project_myTemplateInfos' and there is no table with this name. Instead, there is a table named 'Project' and the hbm.xml file for this is as follows.
<hibernate-mapping package="com.myApp.server.model">
<class name="Project" table="project" dynamic-update="true">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" not-null="true"/>
<property name="displayCity" not-null="true"/>
<list name="myTemplateInfos" cascade="all, delete-orphan" lazy="false" >
<key column="projectId" not-null="false" />
<list-index column="listIndex" />
<composite-element class="com.myApp.server.model.MyTemplateInfo" >
<property name="name" not-null="false" />
<property name="frequency" not-null="false" />
</composite-element>
</list>
</class>
</hibernate-mapping>
As you can see 'myTemplateInfos' is a List within the Project table. After the POJO is created, it looks like something like this.
#ModelBean(IProject.class)
#PermissionIdentifier("project")
public class Project extends ModelObject implements Serializable, IProject {
private Long id;
private String displayCity = "";
private List<IMyTemplateInfo> myTemplateInfos = Lists.newArrayList();
// getters and setters
// hashcode and equals
}
Next we do have another table in the database that is called 'myTemplateInfos' and we do have an hbm xml file for that table as follows ... actually we do not have an hbm xml file for this, so maybe that is the issue. I am going to create a hbm xml file for this and see if that solves the problem.
We do have a POJO for this object 'MyTemplateInfo' though.
If I simply remove his List from the hbm mapping and the Project object, the problem goes away of course, but there is another Set in the hbm.xml file which would give me the same problem, but with a new missing table.
The question becomes how to fix this error message. Is the problem within the hbm xml file for 'Project', or is it in the Project POJO, or the fact that an hbm file does not exist for the 'MyTemplateInfo'?
The solution to this was to fix the hbm xml mapping. Since I haven't had to do this in over 15 years, I am very rusty with it. I can't tell you how happy I was back then to switch to Java POJO's for Hibernate Entity classes with Annotations. But now, unfortunately, I am back having to deal with these xml files again.
The table I had 'mycommunitytemplateinfos' I created a new hbm xml file for it as follows, and put this in the hibernate.cfg.xml file before the other hbm xml mapping.
<hibernate-mapping package="com.myapp.server.model">
<class name="MyTemplateInfo" table="mytemplateinfos">
<id name="id" column="projectId">
<generator class="native"/>
</id>
<property name="name" not-null="false" />
<property name="frequency" not-null="false" />
</class>
</hibernate-mapping>
The mapping between this and the actual class is fine as I have tested this out. I put the hbm file in the hibernate.cfg.xml file before the Project.hbm.xml file and modified the Project.hbm.xml with a one-to-many tag as follows:
<list name="myTemplateInfos" cascade="all, delete-orphan" lazy="false" >
<key column="projectId" not-null="false" />
<list-index column="listIndex" />
<one-to-many class="com.myApp.server.model.MyTemplateInfo" />
</list>
And this seemed to work. I had to do something like this a few times until I got the mapping right. In this day of age, there isn't a lot of information about hbm xml files. Hibernate 5 does use these, but I understand that the preferred way is annotated Java POJO's. Unfortunately, I am stuck in a situation where I can't do that yet.
I am a beginner in Hibernate and I have the below code in one of my projects:
ShortHand o = new ShortHand();
Session sess = noprobs.getSessionFactory().openSession();
sess.getTransaction().setTimeout(noprobs.xActionTimeout);
tx = sess.beginTransaction();
sess.save(o);
For which I get the below error:
ERROR:
org.hibernate.HibernateException: could not determine type of dynamic entity
at org.hibernate.impl.SessionImpl.guessEntityName(SessionImpl.java:1770)
at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1338)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519)
at cool.wxhy.tms.xyz.ABCD.persistInDb(ABCD.java:235)
at cool.wxhy.tms.xyz.ABCD.subscribeToAmps(ABCD.java:144)
at cool.wxhy.tms.xyz.ABCD.hot(ABCD.java:102)
at cool.wxhy.service.impl.wxhyBase.start(wxhyBase.java:250)
at cool.wxhy.service.api.hello.startAllServices(hello.java:211)
at cool.wxhy.service.impl.heyhi.main(heyhi.java:43)
I am using the HIbernate 3.2.6 jar
I am using the xml config for the HIbernate and not the annotations one. Can someone please help on the issue.
Hibernate Mapping file:
<hibernate-mapping package="bofa.pioneer.tms.objects">
<class name="ShortHand" table="ShortHand">
<id name="key" column="id" unsaved-value="null" type="string" >
<generator class="assigned" />
</id>
<property name="animal" column="animal" type="string"/>
<property name="dog" column="dog" type="string"/>
Entity
public class ShortHand extends LongHand {
//getters and setters are present in the parent LongHand
}
I am trying to creating java web application which depends on several java projects. I need to refer to DTO class in another project, for hibernate mapping file. But while running the application with tomcat, I get persistent class not known: exception.
My DTO and hbm file structure in projects are like following,
common-api/java/src/com/test1/dto/Manager.java (package - com.test1.dto)
common-api/java/config/hibernate/manager.hbm.xml
new-api/java/src/com/test2/dto/Depeartment.java (package - com.test2.dto)
new-api/java/config/hibernate/department.hbm.xml
Department DTO classes has a Manager objec as a property.
public Class Department {
private Manager manager;
}
Department hibernate mapping file contains,
<hibernate-mapping>
<class name="com.test2.dto.Department" table="department">
<id name="id" column="id" type="integer">
<generator class="increment" />
</id>
...
<one-to-one name="manager" class="com.test1.dto.Manager" cascade="save-update" >
</one-to-one>
</class>
Seems the class attribute value is not resolved by hibernate. It's highly appreciate if you guys can suggest me what I can do for this ?
Just include all mapping files in your top level hibernate.cfg.xml , eg:
<hibernate-configuration>
<session-factory ... >
<mapping resource="org/hibernate/auction/Item.hbm.xml"/>
<mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
</session-factory>
</hibernate-configuration>
See http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html#configuration-xmlconfig
I can not run my hibernate application. I'm constantly getting this error:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/MAG/.m2/repository/org/slf4j/slf4j-jdk14/1.7.2/slf4j-jdk14-1.7.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/MAG/.m2/repository/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.JDK14LoggerFactory]
2013-02-14 14:49:05 org.hibernate.cfg.Environment <clinit>
INFO: Hibernate 3.3.0.SP1
2013-02-14 14:49:05 org.hibernate.cfg.Environment <clinit>
INFO: hibernate.properties not found
2013-02-14 14:49:05 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: Bytecode provider name : javassist
2013-02-14 14:49:05 org.hibernate.cfg.Environment <clinit>
INFO: using JDK 1.4 java.sql.Timestamp handling
2013-02-14 14:49:05 org.hibernate.cfg.Configuration configure
INFO: configuring from resource: /hibernate.cfg.xml
2013-02-14 14:49:05 org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: Configuration resource: /hibernate.cfg.xml
2013-02-14 14:49:05 org.hibernate.cfg.Configuration addResource
INFO: Reading mappings from resource : model/man/Man.hbm.xml
2013-02-14 14:49:06 org.hibernate.util.XMLHelper$ErrorLogger error
SEVERE: Error parsing XML: XML InputStream(25) Attribute "name" must be declared for element type "many-to-many".
2013-02-14 14:49:06 org.hibernate.util.XMLHelper$ErrorLogger error
SEVERE: Error parsing XML: XML InputStream(33) Attribute "name" must be declared for element type "many-to-many".
2013-02-14 14:49:06 org.hibernate.util.XMLHelper$ErrorLogger error
SEVERE: Error parsing XML: XML InputStream(38) The content of element type "set" must match "(meta*,subselect?,cache?,synchronize*,comment?,key,(element|one-to-many|many-to-many|composite-element|many-to-any),loader?,sql-insert?,sql-update?,sql-delete?,sql-delete-all?,filter*)".
The idea of my program is that:
Man is super class for Owner and Renter.
Owner can have many Flats but Flat can have one Owner.
Renter can have many RenterBills but RenterBill can have one Renter.
Renter can have many Flats and Flats can have many renters.
My Man.hbm.xml:
<class name="Man" table="MEN">
<id name="id" column="MAN_ID">
<generator class="native" />
</id>
<property name="pesel" column="MAN_PESEL" />
<property name="idNumber" column="MAN_ID_NUMBER" />
<property name="email" column="MAN_EMAIL" />
<property name="name" column="MAN_NAME" />
<property name="surname" column="MAN_SURNAME" />
<property name="telephoneNumber" column="MAN_TELEPHONE_NUMBER" />
<many-to-one name="address" column="ADDRESS_ID" not-null="true" />
<joined-subclass name="Owner" table="OWNERS">
<key column="MAN_ID" />
<property name="password" column="OWNER_PASSWORD" not-null="true" />
<property name="seed" column="OWNER_SEED" not-null="true" />
<set name="flats" table="OWNER_FLATS">
<key column="MAN_ID" />
<many-to-many name="flats" column="FLAT_ID" class="Flat" />
</set>
</joined-subclass>
<joined-subclass name="Renter" table="RENTERS">
<key column="MAN_ID" />
<set name="flats" table="RENTER_FLATS">
<key column="MAN_ID" />
<many-to-many name="flats" column="FLAT_ID" class="Flat" />
</set>
<set name="bills" table="RENTER_BILLS">
<key column="MAN_ID" />
<many-to-one name="bills" column="RENTER_BILL_ID" class="RenterBill" />
</set>
</joined-subclass>
</class>
Java classes:
Man.java
package model.man;
import model.addresses.Address;
public abstract class Man {
private int id;
private String pesel;
private String idNumber;
private String email;
private String name;
private String surname;
private String telephoneNumber;
private Address address;
/* getters setters */
}
Owner.java
package model.man;
import java.util.Iterator;
import java.util.Set;
import model.flat.Flat;
public class Owner extends Man implements Iterable<Flat> {
private String password;
private String seed;
private Set<Flat> flats;
/* getters setters */
}
Renter.java
package model.man;
import java.util.HashSet;
import java.util.Set;
import model.bills.RenterBill;
import model.flat.Flat;
public class Renter extends Man {
private Set<Flat> flats = new HashSet<Flat>();
private Set<RenterBill> bills = new HashSet<RenterBill>();
/* getters setters */
}
SEVERE: Error parsing XML: XML InputStream(25) Attribute "name" must be declared for element type "many-to-many".
2013-02-14 14:49:06 org.hibernate.util.XMLHelper$ErrorLogger error
SEVERE: Error parsing XML: XML InputStream(33) Attribute "name" must be declared for element type "many-to-many".
2013-02-14 14:49:06 org.hibernate.util.XMLHelper$ErrorLogger error
SEVERE: Error parsing XML: XML InputStream(38) The content of element type "set" must match "(meta*,subselect?,cache?,synchronize*,comment?,key,(element|one-to-many|many-to-many|composite-element|many-to-any),loader?,sql-insert?,sql-update?,sql-delete?,sql-delete-all?,filter*)".
Try removing the 'name' attribute from your many-to-many tag.
UPDATE
You have a set mapped as a many-to-one as well. This typically shows up in your Java POJO as a single instance of the referenced class. You may have meant to use a one-to-many tag there.
I have the following class:
package lt.vic.valdos.domain.valda;
public class Valda implements java.io.Serializable {
private long id;
private Long valdosKodas;
public long getId() {
return id;
}
public Long getValdosKodas() {
return valdosKodas;
}
}
and the following orm.xml:
<?xml version="1.0"?>
<entity-mappings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_1.xsd"
version="2.1">
<entity class="lt.vic.valdos.domain.valda.Valda">
<table name="VALDOS" schema="VLD" />
<attributes>
<id name="id" />
<basic name="id">
<column name="vld_id" />
<return-insert return-only="true" />
</basic>
<basic name="valdosKodas">
<column name="valdos_kodas" />
</basic>
</attributes>
</entity>
</entity-mappings>
When I deploy this in glassfish, i get the following error:
Exception [EclipseLink-7215] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Could not load the field named [id] on the class [class lt.vic.valdos.domain.valda.Valda]. Ensure there is a corresponding field with that name defined on the class.
The class is in a jar that is included into a web application as a maven dependency. The orm.xml is in /WEB-INF/classes/META-INF of the web application.
What am I doing wrong?
Figured this one out myself. For some reason EclipseLink requires a setter on a class. Once I add private setters everything seems fine. Why the setters are needed (mapping accessors should default to FIELD) remains a mystery but it is not that important for me. Adding access="FIELD" to all entity attributes also fixes the problem without the setters.
You should be specifying the id as generated using the IDENTITY strategy:
<id name="id">
<column name="vld_id"/>
<generated-value strategy="IDENTITY"/>
</id>
This strategy will automatically read the database provided id back into the new object upon successful commit. The EclipseLink returning statement functionality is only applicable to basic mappings because id is already covered by Identity ID generation.
I think you have to add the column description for the id column to your id element, instead of using an extra basic element. As in <id name="id"> <column name="vld_id" /> ... </id>, without an extra <basic name="id"> ....
From my own experience (some time ago now), it's probably easier to use annotations to define your mappings.