one to one relationship with hibernate - java

I try to create a one to one relationship between two tables.
One of them is Person:
public class Person implements Serializable {
static final long serialVersionUID = 1L;
private long id;
private String _email;
private String _pass;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return _email;
}
public void set_email(String _email) {
this._email = _email;
}
public String getPass() {
return _pass;
}
public void set_pass(String _pass) {
this._pass = _pass;
}
}
and the second is ReqC2dmRegId table:
public class ReqC2dmRegId implements Serializable {
private static final long serialVersionUID = 1L;
Person person;
String C2dmid;
private long id;
public ReqC2dmRegId(){}
public String getC2dmid() {
return C2dmid;
}
public void setC2dmid(String c2dmid) {
C2dmid = c2dmid;
}
public ReqC2dmRegId(Person person, String C2dmid) {
super();
this.person = person;
this.C2dmid = C2dmid;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
Now, in my program, I always create the Person first and only when I need I add this ReqC2dmRegId.
Now, what I try to do is to link this two tables. I mean, when I persist this ReqC2dmRegId (of course I add to the person in ReqC2dmRegId the right id) I want my ReqC2dmRegId to update or save a new row with the right Person id.
These are my hbm files:
ReqC2dmRegId.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">
<!-- Generated Mar 26, 2012 11:29:57 AM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="c2dm.ReqC2dmRegId" table="REQC2DMREGID">
<id name="id" type="long">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person" class="Entities.Person" cascade="all" />
<property name="C2dmid" type="java.lang.String">
<column name="C2DMID" />
</property>
</class>
</hibernate-mapping>
Person.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">
<!-- Generated Mar 26, 2012 11:29:57 AM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="Entities.Person" table="PERSON">
<id name="id" type="long">
<column name="ID" />
<generator class="increment" />
</id>
<property name="_email" type="java.lang.String" access="field">
<column name="_EMAIL" />
</property>
<property name="_pass" type="java.lang.String" access="field">
<column name="_PASS" />
</property>
</class>
</hibernate-mapping>
What am I doing wrong?
When I try to run:
//this should to update or save the object in DB
public void update (Object query){
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//em.createNativeQuery(query).executeUpdate();
em.merge(query);
em.flush();
em.getTransaction().commit();
em.close();
}
I get :
attempted to assign id from null one-to-one property:Person
In the end, it should look like this:
Person
**id email _pass**
2 lala#gmail.com 1234
ReqC2dmRegId
**id REQC2DMREGID**
2 ffgghhjj
Update:
after i gave up try to understand way it's not working
i change my ReqC2dmRegId.hbm.xml
to look like this (many-to-one):
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated Mar 27, 2012 9:58:08 PM by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping>
<class name="c2dm.ReqC2dmRegId" table="REQC2DMREGID">
<id name="id" type="long">
<column name="ID" />
<generator class="identity" />
</id>
<many-to-one name="person" class="Entities.Person" fetch="join" unique="true" cascade="save-update" not-null="true" >
<column name="PERSON" />
</many-to-one>
<property name="C2dmid" type="java.lang.String">
<column name="C2DMID" />
</property>
</class> </hibernate-mapping>
and this is working fine the problem is when i try to modify ReqC2dmRegId table
with my update method it create a now row with the same personid
id person_id C2dmid
1 3 asd123
2 3 dfvghj
way it's not update the right row instated create a new one and although i make the "many to one" property to be unique="true"?
thanks in advance

You have to be clear about the kind of relation: Is one-to-one or many-to-one?
Look like is a many-to-one unidirectional relation.
Here is an example with Annotations:
#Entity
#Table(name="PERSON")
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String _email;
private String _pass;
//getters and setters
}
And the other class:
#Entity
#Table(name="ReqC2dmRegId")
public class ReqC2dmRegId {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#ManyToOne
#JoinColumn(name = "PERSON_ID")
private Person person;
//getters and setters
}

Related

How to connect Hibernate with Postgres in Intelij using Maven? [duplicate]

I have written few codes for inserting data into my SQL database. Actually, I am trying to learn Struts 2 with Hibernate. But, unfortunately I am facing a problem after submitting my form.
I could not find the reason for this error message. My try & catch block throws error like:
Exception in saveOrUpdate() Rollback :org.hibernate.MappingException: Unknown entity: v.esoft.pojos.Employee
Pojo(Employee.java):
#Entity
#Table(name = "employee", catalog = "eventusdb")
public class Employee implements java.io.Serializable {
private Integer empId;
private String name;
private String website;
public Employee() {
}
public Employee(String name, String website) {
this.name = name;
this.website = website;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "emp_id", unique = true, nullable = false)
public Integer getEmpId() {
return this.empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
#Column(name = "name", nullable = false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "website", nullable = false, length = 65535)
public String getWebsite() {
return this.website;
}
public void setWebsite(String website) {
this.website = website;
}
}
also having Employee.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">
<!-- Generated Sep 10, 2013 4:29:04 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="v.esoft.pojos.Employee" table="employee" catalog="eventusdb">
<id name="empId" type="java.lang.Integer">
<column name="emp_id" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" not-null="true" />
</property>
<property name="website" type="string">
<column name="website" length="65535" not-null="true" />
</property>
</class>
</hibernate-mapping>
If the entity isn't mapped, you should inspect the hibernate configuration. Hibernate is ORM framework used to map pojos (entities) to the database schema objects. You didn't configure or hibernate couldn't find mapping for the object Employee. The configuration file is hibernate.cfg.xml should contain the mapping to the resource Employee.hbm.xml. Suppose this file is in the same folder as Employee class. Then the mapping will be
<mapping resource="v/esoft/pojos/Employee.hbm.xml"/>
Another approach if you used an annotation based configuration, then you should use class attribute to map to the pojo that contains Hibernate/JPA annotations.
<mapping class="v.esoft.pojos.Employee"/>
Note, annotation based Configuration might be different depending on version of Hibernate and may require additional libraries.

Hibernate auto_increment MySQL

I am using Eclipse, Xammp (tomcat and MySQL DB) and Hibernate.
this all works good, but I can't create that the ID from the Entity will be auto_increment in the Database
My Entity:
package com.jwt.hibernate.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
#Entity
public class User {
#Id
#GenericGenerator(name="generator", strategy="increment")
#GeneratedValue(generator="generator")
private Long userId;
private String userName;
private String password1;
private String email;
private String phone;
private String city;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword1() {
return password1;
}
public void setPassword1(String password1) {
this.password1 = password1;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
I create a hbm.xml for this Entity with a Plugin from Hibernate and use Hibernate XML Mapping file(hbm.xml):
Created 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">
<!-- Generated 06.05.2016 11:59:26 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.jwt.hibernate.bean.User" table="USER">
<id name="userId" type="java.lang.Long">
<column name="USERID" />
<generator class="assigned" />
</id>
<property name="userName" type="java.lang.String">
<column name="USERNAME" />
</property>
<property name="password1" type="java.lang.String">
<column name="PASSWORD1" />
</property>
<property name="email" type="java.lang.String">
<column name="EMAIL" />
</property>
<property name="phone" type="java.lang.String">
<column name="PHONE" />
</property>
<property name="city" type="java.lang.String">
<column name="CITY" />
</property>
</class>
</hibernate-mapping>
My 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.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="hbm2ddl.auto">create-drop</property>
<property name="show_sql">true</property>
<mapping resource="/com/jwt/hibernate/bean/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
If i start my Code, the Console do:
Hibernate: drop table if exists USER
Hibernate: create table USER (USERID bigint not null, USERNAME varchar(255), PASSWORD1 varchar(255), EMAIL varchar(255), PHONE varchar(255), CITY varchar(255), primary key (USERID))
Every thing is fine but my ID isn't auto_increment and I don't know why.
I tried a lot of Annotations.
other Annotations for Example ManyToMany or ManyToOne works, but nut the #GeneratedValue
Use
<id name="userId" type="java.lang.Long">
<column name="USERID" />
<generator class="native" />
</id>
Instead of following line
<id name="userId" type="java.lang.Long">
<column name="USERID" />
<generator class="assigned" />
</id>
You can do use this annotations on your getUserId method :
#Id
#GenericGenerator(name = "id_generator", strategy = "increment")
#GeneratedValue(generator = "id_generator")
#Column(name = "id", unique = true, nullable = false)
public Long getUserId() {
return userId;
}
or you can also do this in your current code just specify #Column on getUserId method
#Column(name = "id", unique = true, nullable = false)
public Long getUserId() {
return userId;
}
If you will use annotations, this is pretty enough
#Id
#GeneratedValue
#Column(name = "id")
public Long getUserId() {
return userId;
}

Hibernate - Mapping association on un-related objects in xml

I have 2 classes:
User
RentedCar
public class User implements Serializable{
private String userName;
private Integer userId;
private String userParent;
}
public class RentedCar implements Serializable{
private Date stopDate;
private Date startDate;
private String carName;
private Integer carId;
private Integer userId; // Some userId from User.
}
These classes have their respective hbm.xml files. The underlying tables are un-related. Which means that I know that the userId in RentedCar is associated with the userId in User but there is no PK/FK relationship between them. I need to add a many-to-one association between RentedCar and User and one-to-many association between User and RentedCar. How should I do this in the hbm.xml files ?
These are the xml mappings:
<?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="User" table="user">
<composite-id>
<key-property name="userName" column="user_name" type="string"/>
<key-property name="userParent" column="user_parent" type="string"/>
</composite-id>
<property name="userId" column="user_id" type="int"></property>
</class>
</hibernate-mapping>
<?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="RentedCar" table="rented_car">
<composite-id>
<key-property name="stopDate" column="stop_date" type="date" />
<key-property name="carId" column="car_id" type="int" />
<key-property name="userId" column="user_id" type="int" />
</composite-id>
<property name="startDate" column="start_date" type="date"></property>
<property name="carName" column="car_name" type="float"></property>
</class>
</hibernate-mapping>
I think you should have something in your classes show that there is one-to-many relationship in order to do this in hbm.xml files :
public class User implements Serializable{
private String userName;
private Integer userId;
private String userParent;
private Set<RentedCar> rentedCars;
}
public class RentedCar implements Serializable{
private Date stopDate;
private Date startDate;
private String carName;
private Integer carId;
private User user;
}
Then in RentedCar.hbm.xml you can inside use :
<many-to-one name="user" class="User">
<column name="userId" not-null="true"></column>
</many-to-one>
And in User.hbm.xml :
<set name="rentedCars" table="rented_car" fetch="select">
<key>
<column name="userId" not-null="true"></column>
</key>
<one-to-many class=" RentedCar "/>
</set>
This tutorial may help you http://www.tutorialspoint.com/hibernate/hibernate_one_to_many_mapping.htm

hibernate change the column name in a select

I have a table (node) with 3 data
- id(pk)
- question
- result
and 2 foreign key (many-to-one)
- LEFT_ID
- RIGHT_ID
here my hbm
<?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="com.beans.Nodes" table="node">
<id name="id" type="int" access="field">
<column name="id" />
<generator class="assigned" />
</id>
<property name="question" type="java.lang.String">
<column name="question" />
</property>
<property name="result" type="java.lang.String">
<column name="result" />
</property>
<many-to-one column="LEFT_ID" name="left" class="com.beans.Nodes" insert="false" update="false"></many-to-one>
<many-to-one column="RIGHT_ID" name="right" class="com.beans.Nodes" insert="false" update="false"></many-to-one>
</class>
</hibernate-mapping>
and my bean with getter/setter on LEFT/RIGHT_ID
#Entity
#Table (name = "node")
public class Nodes
{
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column (name = "question")
private String question;
#Column ( name = "result")
private String result;
private Nodes LEFT_ID;
private Nodes RIGHT_ID;
public Nodes getLeftNodes()
{
return LEFT_ID;
}
public void setLeftNodes(Nodes LEFT_ID)
{
this.LEFT_ID=LEFT_ID;
}
public Nodes getRightNodes()
{
return RIGHT_ID;
}
public void setRifhtNodes(Nodes right)
{
this.RIGHT_ID=right;
}
}
But when i deploy my project, i have this error
**Query: ReadAllQuery(referenceClass=Nodes sql="SELECT id, question, result, LEFT_ID_id, RIGHT_ID_id FROM node")**
When hibernate is a select, he change the name of the column. LEFT_ID becomes LEFT_ID_id and inevitably he finds nothing !
Why hibernate change the name of the LEFT_ID column ?
thanks

Why am I getting Mapping Exception?

I am getting :
org.hibernate.MappingException: Foreign key (FKBB979BF4266AA123:address [a_id]))
must have same number of columns as the referenced
primary key (address [p_id,a_id])
as I try to run the following (though incomplete) snippet :
public static void main(String args[]) {
Configuration config = new Configuration().configure();
SessionFactory sessFact = config.buildSessionFactory();
Session sess = sessFact.openSession();
Transaction trans = sess.beginTransaction();
}
The hibernate mapping xml is shown below :
<class name="pojo.Person" table="person">
<id column="p_id" name="personID">
<generator class="increment" />
</id>
<property name="personName" column="p_name" />
<set name="addressSet" table="address" cascade="all">
<key column="p_id" />
<many-to-many class="pojo.Address" column="a_id" />
</set>
</class>
<class name="pojo.Address" table="address">
<id column="a_id" name="addressID">
<generator class="foreign" />
</id>
<property name="address" column="address" />
</class>
I am trying a many to many association between Person and Address class.
What is the reason for this exception ?
I have created two tables person and address using these sql commands :
CREATE TABLE person(p_id INTEGER,p_name TEXT,PRIMARY KEY(p_id));
CREATE TABLE address(a_id INTEGER,address TEXT);
POJO
Person
public class Person {
private int personID;
private String personName;
private Set addressSet;
public int getPersonID() {
return personID;
}
public void setPersonID(int personID) {
this.personID = personID;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public Set getAddressSet() {
return addressSet;
}
public void setAddressSet(Set addressSet) {
this.addressSet = addressSet;
}
Address
public class Address {
private int addressID;
private String address;
private Set personSet;
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Set getPersonSet() {
return personSet;
}
public void setPersonSet(Set personSet) {
this.personSet = personSet;
}
}
For a ManyToMany Relationshhip you need a dedicated mapping table
6.2.4. Collections of values and many-to-many associations
i.e. You need something like a PersonAddress Table
CREATE TABLE personaddress (p_id integer, a_id integer)
Where p_id is a FK Reference to the Person Table and a_id a FK Reference to the Address Table
You need to specify different table name for many-to-many association as it's handled by a separate table:
<class name="pojo.Person" table="person">
<id column="p_id" name="personID">
<generator class="increment" />
</id>
<property name="personName" column="p_name" />
<set name="addressSet" table="person_address" cascade="all">
<key column="p_id" />
<many-to-many class="pojo.Address" column="a_id" />
</set>
</class>
Note that <set> now references to person_addresses table. With default configuration, Hibernate is able to create it automatically.
There's another mistake that I see: ID generator for Address entity should not be foreign, it's usually used in 1-to-1 relationships (uses ID of another associated object). You can use the same 'increment' use used for Person entity:
<class name="Address" table="address">
<id column="a_id" name="addressID">
<generator class="increment" />
</id>
<property name="address" column="address" />
</class>
You need to create a reference table:
CREATE TABLE PersonsAddresses (personId BIGINT, addressId BIGINT)
and change the mapping of the set to this:
<set name="addressSet" table="PersonsAddresses" order-by="personId">
<key column="personId" foreign-key="p_id"/>
<many-to-many column="addressId" node="a_id" class="pojo.Address" />
</set>

Categories

Resources