I can't insert foreign key - java

I have a node db with five pieces of data:
id(int, PK)
question(varchar)
result(varchar)
left_id(int, FK)
right_id(int, FK)
and two foreign keys in the same table
left_id -> id
right_id -> id
here is my bean
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column(name="id")
#NotNull
private int id;
#Column (name = "question")
private String question;
#Column ( name = "result")
private String result;
#OneToOne(fetch= FetchType.LAZY)
#JoinColumn(name="left_id", referencedColumnName="id", insertable=true, updatable=true)
private Nodes left;
#OneToOne(fetch= FetchType.LAZY)
#JoinColumn(name="right_id", referencedColumnName="id", table="node", insertable=true, updatable=true)
private Nodes right;
and here is my dao
public void insert_question(String question, int left) throws HibernateException
{
try
{
Session session = getSession();
Transaction tx = session.beginTransaction();
Nodes node = new Nodes();
Nodes leftNode = new Nodes();
//insert question
node.setQuestion(question);
// insert left_id with fk
leftNode.setId_node(left);
node.setLeftNodes(leftNode);
session.saveOrUpdate(node);
tx.commit();
session.close();
}
catch (HibernateException e)
{
e.printStackTrace();
}
}
I have a same insert method for result but without foreign key.
My new question and new result are insert my db but not my left_id.
In Eclipse, hibernate tell me
Infos: Hibernate: select nodes_.id, nodes_.question as question0_, nodes_.result as result0_ from node nodes_ where nodes_.id=?
Infos: Hibernate: insert into node (question, result, id) values (?, ?, ?)
Infos: Hibernate: insert into node (question, result, id) values (?, ?, ?)
When hibernate insert a new data, why there are no left/right_id ?
thanks
EDIT:
I changed my hbm. Before it was like that
<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>
<one-to-one name="left" class="com.beans.Nodes" access="field"></one-to-one>
<one-to-one name="right" class="com.beans.Nodes" access="field"></one-to-one>
</class>
</hibernate-mapping>
and now it's like that
<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" not-null="false"/>
</property>
<property name="result" type="java.lang.String">
<column name="result" not-null="false"/>
</property>
<many-to-one name="Left"
column="left_id"
unique="true"
not-null="false"
/>
<many-to-one name="Right"
column="right_id"
unique="true"
not-null="false"
/>
</class>
</hibernate-mapping>
and it's works !

Related

Get user data between two date in Hibernate Java

i have an hibernate entity called user.I want to get the list of users who are between two dates a date interval. Example, I have a date D1 and I want to know the people hired between my hiDate and my depDate.
Here is the mapping of the hibernate file of my user entity
<class name="com.bam.model.User" table="USER">
<composite-id class="com.bam.model.UserId" name="id">
<key-property name="idUser" type="java.lang.String">
<column name="ID_USER" not-null="true" precision="0" scale="30" sql-type="varchar"/>
</key-property>
<key-property name="idCompany" type="java.lang.String">
<column name="ID_COMPANY" not-null="true" precision="0" scale="30" sql-type="varchar"/>
</key-property>
</composite-id>
<property name="gender" type="java.lang.String">
<column name="GENDER" not-null="false" precision="0" scale="4" sql-type="varchar"/>
</property>
<property name="firstname" type="java.lang.String">
<column name="FIRSTNAME" not-null="false" precision="0" scale="100" sql-type="varchar"/>
</property>
<property name="lastname" type="java.lang.String">
<column name="LASTNAME" not-null="false" precision="0" scale="100" sql-type="varchar"/>
</property>
</class>
Here is also the class of my user entity.
#XmlRootElement(name = "user")
public class User implements Serializable {
#XmlElement(name = "id")
private UserId id;
#XmlElement(name = "gender")
private String gender;
#XmlElement(name = "firstName")
private String firstname;
#XmlElement(name = "lastName")
private String lastname;
}
The query that I will write with the hql language is this one :
Query query = session.createQuery("SELECT * FROM USER us oh WHERE DATE_FORMAT(us.HI_DATE,'%dd-%mm-%YYYY') <= :from_date <= DATE_FORMAT(us.DEP_DATE'%dd-%mm-%YYYY') ");
query.setParameter( "from_date ", from_date );
but it doesn't work, any idea ?
you can try this.
Do you need to format the dates?
Query query = session.createQuery("FROM USER us WHERE :from_date between us.hiDate and us.depDate");
query.setParameter( "from_date ", from_date );

java.lang.Object; cannot be cast to shoppingbasket.Product

I am trying to retrieve a list of products with they're associated offers. After iterating through the result of the query I want to be able to use the getters/setters from the products class but I know it's not working because the query is not returning an instance of Product.
function to grab the products:
public List<Product> getProducts() {
factory = (new Configuration()).configure().buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();
List<Product> products = new ArrayList<Product>();
Query query = session.createQuery("from Product p INNER JOIN p.offers");
//The castList is declared and explained at the bottom of listing
List<Product> list = query.list();
Iterator<Product> iter = list.iterator();
while (iter.hasNext()) {
Product product = iter.next();
System.out.println(product);
}
}
Hibernate mapping for Offer:
<hibernate-mapping>
<class name="shoppingbasket.Offer" table="offers">
<id name="offerID" type="integer" access="field">
<column name="OfferID" />
<generator class="assigned" />
</id>
<property name="offerDescription" type="java.lang.String" access="field">
<column name="OfferDescription" length="60" not-null="true"/>
</property>
<property name="shortDescription" type="java.lang.String" access="field">
<column name="ShortDescription" length="10" not-null="false"/>
</property>
<property name="TFTPOTGroup" type="java.lang.Integer" access="field">
<column name="TFTPOTGroup" length="4" not-null="false" default="null"/>
</property>
<property name="discountPercentage" type="java.lang.Double" access="field">
<column name="DiscountPercentage" not-null="false" default="null"/>
</property>
</class>
Hibernate mapping for Product:
<hibernate-mapping>
<class name="shoppingbasket.Product" table="products">
<id name="productID" type="integer" access="field">
<column name="ProductID" />
<generator class="assigned" />
</id>
<property name="offerID" type="java.lang.Integer" access="field">
<column name="OfferID" />
</property>
<property name="productName" type="java.lang.String" access="field">
<column name="ProductName" length="40" not-null="true"/>
</property>
<property name="unitPrice" type="java.math.BigDecimal" access="field">
<column name="UnitPrice"/>
</property>
<one-to-one name="offers" class="shoppingbasket.Offer" />
</class>
Product class:
public class Product implements java.io.Serializable {
private Integer productID;
private Integer offerID;
private String productName;
private BigDecimal unitPrice;
private Offer offer;
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getOfferID() {
return this.offerID;
}
public void setOfferID(Integer offerID) {
this.offerID = offerID;
}
public Offer getOffers() {
return offer;
}
public void setOffers(Offer offer) {
this.offer = offer;
}
//more getters/setters
}
Offer class:
public class Offer
{
private Integer offerID;
private String offerDescription;
private String shortDescription;
private Integer TFTPOTGroup;
private Double discountPercentage;
public Integer getOfferID() {
return offerID;
}
public void setOfferID(Integer offerID) {
this.offerID = offerID;
}
//more getters/setters
}
Any help would be hugely appreciated
#Potential Unnecessary Projections Data:
Since you're not specifying SELECT clause in the query and putting explicit joins, hibernate will return 2 objects per row (Product, Offers), wherein Product object might already be populated with the Offer data due to underlying mapping associations.
Try adding select clause to the query and see if it casts correctly
Add SELECT p FROM ... to the query

Hibernate parent/child association. Update parent make child lost all associated objects

I have following classes.
public class Employee {
private int id;
private String firstName;
private String lastName;
private Address address;
private Employer employer;
}
public class Employer {
private int id;
private String name;
private Set<Employee> employees;
}
public class Address {
private int id;
}
public class Project{
private int id;
}
<hibernate-mapping>
<class name="me.hibernate.basic.xml.Employee" table="EMPLOYEE">
<id name="id" type="int" column="id">
<generator class="native" />
</id>
<property name="firstName" column="first_name" type="string" />
<property name="lastName" column="last_name" type="string" />
<many-to-one name="address" column="address" unique="true" class="me.hibernate.basic.xml.Address"/>
<set name="projects" cascade="save-update, delete-orphan" sort="natural">
<key column="employee_proj_id" />
<one-to-many class="me.hibernate.basic.xml.Project" />
</set>
<many-to-one name="employer" column="employer" class="me.hibernate.basic.xml.Employer"/>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="me.hibernate.basic.xml.Employer" table="EMPLOYER">
<id name="id" type="int" column="id">
<generator class="native" />
</id>
<property name="name" column="name" type="string" />
<set name="employees" cascade="save-update, delete-orphan" table="EMPLOYEE">
<key column="employer"/>
<one-to-many class="me.hibernate.basic.xml.Employee" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="me.hibernate.basic.xml.Address" table="ADDRESS">
<meta attribute="class-description"> This class contains the address detail. </meta>
<id name="id" type="int" column="id">
<generator class="native" />
</id>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="me.hibernate.basic.xml.Project" table="PROJECT">
<meta attribute="class-description"> This class contains the project detail. </meta>
<id name="id" type="int" column="id">
<generator class="native" />
</id>
</class>
</hibernate-mapping>
In my application I create few Employees and assign an address to them. And add some projects. Then I create an employer and add all the employees to employer. Once I add employees and update the employer, all the employees lose their addresses and projects. How can I do this with keeping lazy loading feature. I don't need to set lazy="false".
Employee emp1 = ME.addEmployee("Zara", "Ali");
Employee emp2 = ME.addEmployee("Daisy", "Das");
Address addr1 = ME.addAddress(35, "xxxxxx Street", "XXXXX", "XY7 0ZZ");
Address addr2 = ME.addAddress(42, "xxxxxx Street", "XXXXX", "XY7 7ZZ");
ME.setAddress(emp1.getId(), addr1);
ME.setAddress(emp2.getId(), addr2);
Set<Project> proj = new HashSet<Project>();
proj.add(new Project("NOVA"));
proj.add(new Project("GTA Simplify"));
proj.add(new Project("Jazz"));
ME.addProjects(emp.getId(), proj);
ME.addProjects(emp.getId(), proj);
All working up to this point.
Set<Employee> emps = new HashSet<Employee>();
emps.add(emp1); emps.add(emp2);
//Add existing employees to employer - Many-to-one bidirectional
Employer employer = ME.addEmployer("XYZ");
ME.addEmployees(employer.getId(), emps);
public Integer addEmployees(Integer employerID, Set<Employee> employees) {
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Employer employer = (Employer) session.get(Employer.class,employerID);
employer.getEmployees().clear();
employer.getEmployees().addAll(employees);
session.update(employer);
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return employerID;
}
Once I added employees, all the foreign key references are lost in the PROJECT.employee_proj_id and EMPLOYEE.address.
Hibernate log:
->Hibernate: update EMPLOYEE set first_name=?, last_name=?, basic=?, address=?, employer=? where id=?
->Hibernate: update EMPLOYEE set first_name=?, last_name=?, basic=?, address=?, employer=? where id=?
->Hibernate: update PROJECT set employee_proj_id=null where employee_proj_id=?
->Hibernate: update PROJECT set employee_proj_id=null where employee_proj_id=?
->Hibernate: update EMPLOYEE set employer=? where id=? ->Hibernate: update EMPLOYEE set employer=? where id=?
I see that you are clearing the employees before you add more employees, which is the root cause of everything. I'm not sure what you are doing when adding addresses, Project, employer etc., You need not clear the employees. If you have cascadetype.all set on the employees then saving the employer will update the newly added employees.
employer.getEmployees().clear();//remove this line.
employer.getEmployees().addAll(employees);

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

HQL returns no results but generated SQL works perfectly on SQL Developer

So I have this query
private static final String GET_LOCK_HISTORY1 = "select lh from UserLockHistoryEntity lh ";
which is executed using this code
List<UserLockHistoryEntity> result = getQuery(GET_LOCK_HISTORY1).list();
This returns an empty array. On the console I get the generated SQL which is
select
userlockhi0_.USER_LOCK_HISTORY_ID as USER_LOC1_15_,
userlockhi0_.LOCK_TYPE as LOCK_TYP2_15_,
userlockhi0_.TIMESTAMP as TIMESTAM3_15_,
userlockhi0_.LOCKED_USER_ID as LOCKED_U4_15_,
userlockhi0_.COMPANY_ID as COMPANY_5_15_,
userlockhi0_.PARTNER_ID as PARTNER_6_15_,
userlockhi0_.IP_ORIGIN as IP_ORIGI7_15_,
userlockhi0_.LOCKED_BY_USER as LOCKED_B8_15_,
userlockhi0_.LOCKED_BY_TYPE as LOCKED_B9_15_,
userlockhi0_.LOCK_REASON as LOCK_RE10_15_
from
ONCPRTDEV.USER_LOCK_HISTORY userlockhi0_
and I paste it on SQL developer which returns me 8 rows (all table records)
Bellow it's my mapping file
<?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 Jan 22, 2014 3:07:58 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="pt.vdf.onc.core.business.entity.user.UserLockHistoryEntity" table="USER_LOCK_HISTORY">
<id name="id" type="java.lang.Long">
<column name="USER_LOCK_HISTORY_ID" />
<generator class="assigned" />
</id>
<property name="lockType">
<column name="LOCK_TYPE" />
<type name="org.hibernate.type.EnumType">
<param name="enumClass">pt.vdf.onc.core.common.type.user.UserLockType</param>
</type>
</property>
<property name="timestamp" type="java.lang.String">
<column name="TIMESTAMP" />
</property>
<property name="userId" type="java.lang.Long">
<column name="LOCKED_USER_ID" />
</property>
<property name="companyId" type="java.lang.Long">
<column name="COMPANY_ID" />
</property>
<property name="partnerId" type="java.lang.Long">
<column name="PARTNER_ID" />
</property>
<property name="ipOrigin" type="java.lang.String">
<column name="IP_ORIGIN" />
</property>
<property name="lockedByUser" type="java.lang.Long">
<column name="LOCKED_BY_USER" />
</property>
<property name="lockedByType">
<column name="LOCKED_BY_TYPE" />
<type name="org.hibernate.type.EnumType">
<param name="enumClass">pt.vdf.onc.core.common.type.user.UserLockByType</param>
</type>
</property>
<property name="lockedReason">
<column name="LOCK_REASON" />
<type name="org.hibernate.type.EnumType">
<param name="enumClass">pt.vdf.onc.core.common.type.user.UserLockReason</param>
</type>
</property>
</class>
</hibernate-mapping>
and entity
public class UserLockHistoryEntity implements java.io.Serializable {
private Long id;
private UserLockType lockType;
private String timestamp;
private Long userId;
private Long companyId;
private Long partnerId;
private String ipOrigin;
private Long lockedByUser;
private UserLockByType lockedByType;
private UserLockReason lockedReason;
//getters and setters here (removed them for simplicity)
}
Table definition:
USER_LOCK_HISTORY_ID NUMBER(38,0)
LOCK_TYPE NUMBER(38,0)
TIMESTAMP DATE
LOCKED_USER_ID NUMBER(38,0)
COMPANY_ID NUMBER(38,0)
PARTNER_ID NUMBER(38,0)
IP_ORIGIN VARCHAR2(30 BYTE)
LOCKED_BY_USER VARCHAR2(50 BYTE)
LOCK_REASON NUMBER(38,0)
LOCKED_BY_TYPE NUMBER
And some rows as an example:
809 0 14.01.22 5003953 1003739 0 127.0.0.1 5003953 2 0
810 0 14.01.22 5003953 1003739 0 127.0.0.1 5003953 2 0
811 0 14.01.22 2054497 621936 0 127.0.0.1 2054497 2 0
Why am I getting an empty result List when the query works perfectly on SQL Developer? Thanks for your help
For
List<UserLockHistoryEntity> result = getQuery(GET_LOCK_HISTORY1).list();
The valid query is
select lh from UserLockHistoryEntity lh
For query
select lh.id from UserLockHistoryEntity lh
The valid result is:
List<Long> result = getQuery(GET_LOCK_HISTORY1).list();
How is your pojo annotated? Is the id field annotated as an id?
public class UserLockHistoryEntity implements java.io.Serializable {
private Long id;
...
#Id
#Column(name = "USER_LOCK_HISTORY_ID", unique = true, nullable = false)
public Long getId() {
return this.id;
}
...
}

Categories

Resources