EDIT :
The problem solved,I didnt write the exactly loaction of the entites in the XML files,Where the one-many-tag.
Im trying to map these classes to database and i get this error :
Exception in thread "main" org.hibernate.MappingException: Association references unmapped class: Reservation
at org.hibernate.cfg.HbmBinder.bindCollectionSecondPass(HbmBinder.java:2557)
at org.hibernate.cfg.HbmBinder$CollectionSecondPass.secondPass(HbmBinder.java:2808)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1695)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at entities.chairandtabletest.main(chairandtabletest.java:39)
I tried to find where is my problem,I read about this exception and i dont understand where is the problem in my program.
The classes :
public class Customer {
private Integer id;
private String fullName;
private String address;
private String email;
private String phoneNumber;
private List<Reservation> reservations = new ArrayList<Reservation>();
}
public class Reservation{
private Integer id;
private String date;
private Integer totalSum;
private boolean isDeliever;
private List<Item> items = new ArrayList<Item>();
}
public class Item {
private Integer id;
private String name;
private Integer price;
}
The tables :
CREATE TABLE ITEM(
item_id INT NOT NULL AUTO_INCREMENT,
item_name VARCHAR(40),
item_price INT NOT NULL,
reservation_id INT,
PRIMARY KEY(item_id)
);
CREATE TABLE RESERVATION(
reservation_id INT NOT NULL AUTO_INCREMENT,
reservarion_date VARCHAR(255),
reservtion_delivery BOOL,
reservation_total_sum INT,
customer_id INT,
PRIMARY KEY(reservation_id)
);
CREATE TABLE CUSTOMERS(
customer_id INT NOT NULL AUTO_INCREMENT,
customer_full_name VARCHAR(40),
customer_address VARCHAR(255),
customer_email VARCHAR(255),
customer_phone_number VARCHAR(20),
PRIMARY KEY(customer_id)
);
The XML files :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/chairandtable?serverTimezone=UTC</property>
<property name="hibernate.connection.username">aliali</property>
<property name="hibernate.connection.password">password</property>
<mapping resource="props/customer.hbm.xml"/>
<mapping resource="props/reservation.hbm.xml"/>
<mapping resource="props/item.hbm.xml"/>
</session-factory>
</hibernate-configuration>
<?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="entities.Customer" table="customers">
<meta attribute="class-description">
This class contain customers details.
</meta>
<id name="id" type="integer" column="customer_id">
<generator class="identity"/>
</id>
<bag name="reservations" cascade="all">
<key column= "customer_id"/>
<one-to-many class="Reservation"/>
</bag>
<property name="fullName" column="customer_full_name" type="string"/>
<property name="address" column="customer_adress" type="string"/>
<property name="email" column="customer_email" type="string"/>
<property name="phoneNumber" column="customer_phone_number" type="string"/>
</class>
</hibernate-mapping>
<?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 ="entities.Reservation" table="reservation">
<meta attribute="class-description">
This class contain reservation detail.
</meta>
<id name ="id" column="reservation_id" type="integer">
<generator class="identity"/>
</id>
<bag name="items" cascade="all">
<key column="reservation_id"/>
<one-to-many class="Item"/>
</bag>
<property name="date" column="reservation_date" type="string"/>
<property name="totalSum" column="reservation_total_sum" type="integer"/>
<property name="isDeliver" column="reservtion_delivery" type="boolean"/>
</class>
</hibernate-mapping>
<?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="entities.Item" table="item">
<id name= "id" column="item_id" type="integer">
<generator class="identity"/>
</id>
<property name="name" column="item_name" type="string"/>
<property name="price" column="item_price" type="integer"/>
</class>
</hibernate-mapping>
I think the problem is the tables i declared , Maybe the are not matching the
xml file.
You need to change the order of *hbm.xml configs to:
<mapping resource="props/item.hbm.xml"/>
<mapping resource="props/reservation.hbm.xml"/>
<mapping resource="props/customer.hbm.xml"/>
And add the "entities" package to all of your one-to-many mappings like this:
<one-to-many class="entities.Item"/>
Related
I am migrating entity mapping from an annotations app to hbm.xml
I error this error and not found the solution. Thanks
java.lang.Exception: Not an entity: class com.enterprise.package.user.domain.User
I have hibernate.cfg.xml in the resources folder, User.hbm.xml in one package and User.class in another
User.hbm.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.enterprise.package.role.domain.User" table="user">
<id name="id" type="java.lang.Long">
<column name="id" />
<generator class="identity" />
</id>
<property name="username" column="username" type="java.lang.String" unique="true"/>
<property name="password" column="password" type="java.lang.String"/>
<many-to-one name="role" column="role_id" class="com.enterprise.package.role.domain.Role" not-null="true"/>
</class>
</hibernate-mapping>
User.class
public final class User {
private Long id;
private String username;
private String password;
private Role role;
public User() {
}
public User(Long id) {
this.id = id;
}
public User(Long id, String username, String password, Role role) {
this.id = id;
this.username = username;
this.password = password;
this.role = role;
}
...
}
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">**</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<mapping package="com/enterprise/package/user/infrastructure/persistence/hibernate/Role.hbm.xml"/>
<mapping package="com/enterprise/package/user/infrastructure/persistence/hibernate/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
I think the package of User class may be wrong in User.hbm.xml (we cant see in your snippet the package of this class)...
In User.hbm.xml instead of
com.enterprise.package.role.domain.User
may be
com.enterprise.package.user.domain.User.
I am getting ClassCastException: at.sheldor5.tr.api.time.RecordType cannot be cast to java.lang.Boolean because Hibernate 5.2.9.FINAL completly ignores my converter:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="at.sheldor5.tr.api.time">
<class name="Record" table="RECORDS">
<id name="id" type="int" column="PK_RECORD_ID">
<generator class="native"/>
</id>
<many-to-one name="user" column="FK_USER_MAPPING_ID" class="at.sheldor5.tr.api.user.UserMapping"/>
<property name="date" type="java.time.LocalDate" column="DATE" index="I_DATE"/>
<property name="time" type="java.time.LocalTime" column="TIME"/>
<property name="type" type="boolean" column="TYPE">
<type name="at.sheldor5.tr.persistence.converter.RecordTypeAttributeConverter"/>
</property>
</class>
</hibernate-mapping>
Converter:
#Converter
public class RecordTypeAttributeConverter implements AttributeConverter<RecordType, Boolean> {
#Override
public Boolean convertToDatabaseColumn(final RecordType attribute) {
if (attribute == null) {
return null;
}
return attribute.getBoolean();
}
#Override
public RecordType convertToEntityAttribute(final Boolean dbData) {
return RecordType.getType(dbData);
}
}
The only thing I can see is that hibernate ignores my converter because of some random things.
Any suggestions (except clean/rebuild which I already tried or hard reset)?
EDIT: my converter won't even gets loaded ...
I have a question about the creation of database schemes by Hibernate.
In our project we have users and groups. Groups have exactly one owner and can have multiple members. A user can be owner and member of multiple groups.
We came up with the following Hibernate mapping:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="model.User" table="ProductUser">
<id name="id" column="userId">
<generator class="native"/>
</id>
<property name="email"/>
<property name="firstName"/>
<property name="lastName"/>
<set name="ownedUserGroups" table="UserGroup" inverse="true">
<key column="userId"/>
<one-to-many class="model.UserGroup"/>
</set>
<set name="userGroups" table="Members" inverse="false" lazy="true" fetch="select">
<key column="userId"/>
<many-to-many column="userGroupId" class="model.UserGroup"/>
</set>
</class>
<class name="model.UserGroup" table="UserGroup">
<id name="id" column="userGroupId">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="owner" class="model.User" column="owner_UserId"/>
<set name="members" table="Members" inverse="true" lazy="true" fetch="select">
<key column="userGroupId"/>
<many-to-many column="userId" class="model.User"/>
</set>
</class>
</hibernate-mapping>
The database scheme Hibernate creates for us looks the following:
Database scheme created by Hibernate
Can somebody explain why usergroup has the userid as a foreign key? (As you can see in the image)
For the sake of completeness, here is the code for User and UserGroup:
public class User {
private int id;
private String firstName;
private String lastName;
private String email;
private Set<UserGroup> ownedUserGroups;
private Set<UserGroup> userGroups;
public User() {
this.ownedUserGroups = new HashSet<>();
this.userGroups = new HashSet<>();
}
public User(String firstName, String lastName, String email) {
this();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
// getters and setters
}
public class UserGroup {
private int id;
private String name;
private User owner;
private Set<User> members;
public UserGroup() {
this.members = new HashSet<>();
}
public UserGroup(String name, User owner, HashSet<User> members) {
this.name = name;
this.owner = owner;
this.members = members;
}
// getters and setters
}
Ok. The problem is with your many-to-one-mapping. What your doing is your trying to set ownedUserGroups to all the groups where the userId equals the id of the current user. However you need to look for all groups where the owner_UserId equals the id of your user. Basically you just need to replace userId with owner_UserId. Your final mapping file should look like this:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="model.User" table="ProductUser">
<id name="id" column="userId">
<generator class="native"/>
</id>
<property name="email"/>
<property name="firstName"/>
<property name="lastName"/>
<set name="ownedUserGroups" table="UserGroup" inverse="true">
<key column="owner_userid"/> <!-- CHANGED -->
<one-to-many class="model.UserGroup"/>
</set>
<set name="userGroups" table="Members" inverse="false" lazy="true" fetch="select">
<key column="userId"/>
<many-to-many column="userGroupId" class="model.UserGroup"/>
</set>
</class>
<class name="model.UserGroup" table="UserGroup">
<id name="id" column="userGroupId">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="owner" class="model.User" column="owner_UserId"/>
<set name="members" table="Members" inverse="true" lazy="true" fetch="select">
<key column="userGroupId"/>
<many-to-many column="userId" class="model.User"/>
</set>
</class>
</hibernate-mapping>
I have three objects USER, CONTACT and ACTION.
Each USER has many CONTACTS and each CONTACT has many ACTIONS
Each CONTACT and ACTION has status assigned to them, e.g. 20 or 60 or...
Please have a look at the data model.
Requirement is to get the CONTACTs having a particular status, or get the CONTACTs whose ACTIONs have that particular status.
E.g. get me CONTACTs with status 20, or CONTACTs who’s ACTIONs have status 20
At the moment I have the following query that is retrieving the CONTACTs with the status 20 and does not considers that status of the ACTIONs
USER
public class User {
private Integer userID;
private String userFirstName;
private String userLastName;
private Set<Contact> contactSet = new HashSet<Contact>();
private Set<Action> actionSet = new HashSet<Action>();
private ContactCriteria contactCriteria;
.
.
.
}
CONTACT
public class Contact implements Serializable {
private Integer contactID;
private Integer contactStatus = 0;
private String givenName;
private String familyName;
private String streetAddress;
private Set<User> userSet = new HashSet<User>();
private Set<Action> actionSet = new HashSet<Action>();
.
.
.
}
ACTION
public class Action implements Serializable {
private Integer actionID;
private Integer actionStatus;
private User user;
private String actionNote;
private Contact contact;
.
.
.
}
Following are my mapping files:
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smallworks.model" schema="smallworksdb">
<class name="User" table="USERACCOUNT">
<id column="USER_ID" length="500" name="userID">
<generator class="increment"/>
</id>
<property column="USER_FIRSTNAME" generated="never" lazy="false" length="100" name="userFirstName"/>
<property column="USER_LASTNAME" generated="never" lazy="false" length="100" name="userLastName"/>
<set cascade="all" fetch="select" lazy="true" name="contactSet" sort="unsorted" table="USER_CONTACT">
<key column="USER_ID"/>
<many-to-many class="com.smallworks.model.Contact"
column="CONTACT_ID" order-by="CONTACT_ID" unique="false"/>
</set>
<!-- one to many mapping with Action -->
<set inverse="true" lazy="true" name="actionSet" sort="unsorted" order-by="ACTION_DUE_DATE" cascade="save-update">
<key column="USER_ID"/>
<one-to-many class="com.smallworks.model.Action"/>
</set>
<!-- one to one mapping with ContactCriteria -->
<one-to-one name="contactCriteria" class="com.smallworks.model.ContactCriteria"
cascade="save-update" lazy="false"></one-to-one>
</class>
</hibernate-mapping>
Contact.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smallworks.model" schema="smallworksdb">
<class name="Contact" table="CONTACT">
<id column="CONTACT_ID" length="500" name="contactID">
<generator class="increment"/>
</id>
<property column="GIVEN_NAME" generated="never" lazy="false"
length="100" name="givenName"/>
<property column="FAMILY_NAME" generated="never" lazy="false"
length="100" name="familyName"/>
<property column="STREET_ADDRESS" generated="never" lazy="false"
length="100" name="streetAddress"/>
<property column="CONTACT_STATUS" generated="never" lazy="false"
name="contactStatus" type="integer"/>
<set inverse="true" lazy="false" name="userSet" sort="unsorted" table="USER_CONTACT">
<key column="CONTACT_ID"/>
<many-to-many class="com.smallworks.model.User" column="USER_ID" unique="false"/>
</set>
<!-- one to many mapping with Action -->
<set inverse="true" lazy="true" name="actionSet" sort="unsorted" order-by="ACTION_DUE_DATE" cascade="save-update">
<key column="CONTACT_ID"/>
<one-to-many class="com.smallworks.model.Action"/>
</set>
</class>
</hibernate-mapping>
Action.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smallworks.model" schema="smallworksdb">
<class name="Action" table="ACTION">
<id column="ACTION_ID" length="500" name="actionID">
<generator class="increment"/>
</id>
<property column="ACTION_STATUS" generated="never" lazy="false"
name="actionStatus" type="integer"/>
<!-- many to one mapping with Contact -->
<many-to-one cascade="save-update"
class="com.smallworks.model.Contact" column="CONTACT_ID" lazy="false"
name="contact" not-null="true" />
<!-- many to one mapping with User -->
<many-to-one class="com.smallworks.model.User" column="USER_ID"
lazy="false" name="user" not-null="true"/>
</class>
</hibernate-mapping>
My existing query is:
Query query = session.createQuery("select distinct c FROM com.smallworks.model.User as u INNER JOIN u.contactSet as c WHERE u.userID=:userIDPara AND c.contactStatus in (:contactStatusPara)");
query.setParameter("userIDPara", user.getUserID());
query.setParameterList("contactStatusPara", statusList);
contactList = query.list();
Add an outer join on c.actions as a and an OR restriction on a.status.
select distinct c FROM com.smallworks.model.User as u INNER JOIN u.contactSet as c LEFT OUTER JOIN c.actionSet a WHERE u.userID=:userIDPara AND (c.contactStatus in (:contactStatusPara) OR a.actionStatus in (: actionStatusPara)
I am following this titorial on roseindia to get basics of Hibernate : "http://roseindia.net/hibernate/hibernate-update.shtml"
My code is as below and getting the error for the same. Please assist me to fix it!
Java Code:
public class UpdateExample {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Session sess = null;
try {
SessionFactory fact = new Configuration().configure().buildSessionFactory();
sess = fact.openSession();
Transaction tr = sess.beginTransaction();
Insurance ins = (Insurance)sess.get(Insurance.class, new Long(1));
ins.setInsuranceName("Jivan Dhara");
ins.setInvestementAmount(20000);
ins.setInvestementDate(new Date());
sess.update(ins);
tr.commit();
sess.close();
System.out.println("Update successfully!");
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
And
public class Insurance {
private String insuranceName;
private double investementAmount;
private Date investementDate;
public String getInsuranceName() {
return insuranceName;
}
public void setInsuranceName(String insuranceName) {
this.insuranceName = insuranceName;
}
public double getInvestementAmount() {
return investementAmount;
}
public void setInvestementAmount(double investementAmount) {
this.investementAmount = investementAmount;
}
public Date getInvestementDate() {
return investementDate;
}
public void setInvestementDate(Date investementDate) {
this.investementDate = investementDate;
}
}
And my contact.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Contact" table="CONTACT">
<id name="id" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="firstName">
<column name="FIRSTNAME" />
</property>
<property name="lastName">
<column name="LASTNAME"/>
</property>
<property name="email">
<column name="EMAIL"/>
</property>
</class>
<class name="Book" table="book">
<id name="lngBookId" type="long" column="id" >
<generator class="increment"/>
</id>
<property name="strBookName">
<column name="bookname" />
</property>
</class>
<class name="Insurance" table="insurance">
<id name="insuranceName" type="String" column="InsuranceName" >
/>
</id>
<property name="investmentAmount">
<column name="InvestmentAmount" />
</property>
<property name="investmentDate">
<column name="InvestmentDate" />
</property>
</class>
</hibernate-mapping>
And the error i am getting is:
"Error reading resource: contact.hbm.xml"
Also I have created db table by name Insurance with those column fields.
Thanks
Sneha
Isn't something missing in the hbm.xml file? It isn't a complete XML file.
You need to place the hbm.xml file together with the compiled class file for your class.
Is this your whole .hbm.xml file? If so, it's incomplete - it lacks proper structure shown here: http://roseindia.net/hibernate/hibernateormapping.shtml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="roseindia.tutorial.hibernate.Contact" table="CONTACT">
<id name="id" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="firstName">
<column name="FIRSTNAME" />
</property>
<property name="lastName">
<column name="LASTNAME"/>
</property>
<property name="email">
<column name="EMAIL"/>
</property>
</class>
</hibernate-mapping>
you have to define two POJO classes
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Book" table="book" >
<id name="lngBookId" column="id" type="long">
<generator class="increment"></generator>
</id>
<property name="strBookName" type="string">
<column name="bookname" sql-type="VARCHAR2(55)"/>
</property>
</class>
<class name="Insurance" table="insurance" >
<property name="firstName" type="string">
<column name="FIRSTNAME" sql-type="VARCHAR2(55)"/>
</property>
<property name="lastName" type="string">
<column name="LASTNAME" sql-type="VARCHAR2(55)"/>
</property>
<property name="email" type="string">
<column name="EMAIL" sql-type="VARCHAR2(55)"/>
</property>
</class>
</hibernate-mapping>