Mapping Hibernate - java

I have 2 Entities: Technologie and Competence
Each competence can have 1 or more Techno
so i have generate the classes by Hibernate
and he gave me 3 classes Model
Technologie
Competence
TechnologieId
and now i'm confused about how to add a technologie
and what is the point of TechnoligieId ?
Technologie.java
public class Technologie implements java.io.Serializable {
private TechnologieId id;
private Competence competence;
private String libelleTechnologie;
}
TechnologieId.java
public class TechnologieId implements java.io.Serializable {
private int idCompetence;
private int idTechnologie;
}
Technologie.hbm.xml
<class name="com.model.Technologie" table="technologie" catalog="gestioncollaborateur">
<composite-id name="id" class="com.model.TechnologieId">
<key-property name="idCompetence" type="int">
<column name="idCompetence" />
</key-property>
<key-property name="idTechnologie" type="int">
<column name="idTechnologie" />
</key-property>
</composite-id>
<many-to-one name="competence" class="com.model.Competence" update="false" insert="false" fetch="select">
<column name="idCompetence" not-null="true" />
</many-to-one>
<property name="libelleTechnologie" type="string">
<column name="libelleTechnologie" length="254" />
</property>
</class>

If the relationship is mentioned correctly in the question. Then why dont you do something like this?
public class Technologie implements java.io.Serializable {
private id;
private Competence competence;
private String libelleTechnologie;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="<yourForeign Key for Competence>")
public Competence getCompetence() {
return competence;
}
}
And the Competence Class such as.
public class Competence implements java.io.Serializable {
private id;
private List<Technologie> technologies;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(mappedBy = "<name of the property of Competence in Technology class>")
public List<Technologies> getTechnologies() {
return technologies;
}
}
Also, this is if the Technology is the managing side of the relationship. Basically, what it means is you will do a save / update on the Technologie primarily which will handle the relationship.
If you do want the #OneToMany side as the managing side. you would have to add the insertable=false, updatable=false attributes in the #JoinColumn annotation for the the getTechnologies method.

Related

Adding lazy=false using annotation in hibernate java

I am having below xml mapping file where they have used many-to-one column,
<hibernate-mapping>
<class name="com.example.offerUser"
table="offerUser">
<id name="offerUserId" type="java.lang.Long">
<column name="OOFER_USER_ID"/>
<generator class="identity"/>
</id>
<many-to-one name="offer"
class="com.example.offer"
fetch="select" lazy="false">
<column name="OFFER_ID"/>
</many-to-one>
<many-to-one name="user"
class="com.example.User"
fetch="select" lazy="false">
<column name="USER_ID"/>
</many-to-one>
</class>
</hibernate-mapping>
and here is annotation code,where i am replacing xml by annotation,but how to replace lazy="false" in annotation.
#Entity
#Table(name = "offerUser")
#JsonIgnoreProperties(ignoreUnknown = true)
public class offerUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "OOFER_USER_ID")
private Long offerUserId;
#ManyToOne(fetch = FetchType.LAZY)
#Fetch(FetchMode.SELECT)
#JoinColumn(name="OFFER_ID")
private offer offer;
#ManyToOne(fetch = FetchType.LAZY)
#Fetch(FetchMode.SELECT)
#JoinColumn(name="USER_ID")
private User user;
}
I searched in google,but i they have not mentioned any thing about setting lazy=false, instead they have used 'Optional = false'.Why is it so.?Please help me on this.
In hibernate annotations ( #ManyToOne ) default fetch type is EAGER.

Don't change the reference to a collection with cascade="all-delete-orphan" while changing properyt in an entity

I am getting above exception when i tried to change the value of an property in the entity but not the collection.
I retrieved value by tinyUrl even though it is not an primary key in the table.
Below is part of the code snippet
Sample sample = retrieveContentByUrl("https://text.com");
sample.setDescription("Sample");
getSession().saveorupdate(sample);
Sample.java
class Sample {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID")
private int id;
#Column(name="TINY_URL")
private int tinyUrl;
#Column(name="DESCRIPTION")
private String description;
#OneToMany(mappedBy="sample",fetch=FetchType.LAZY, cascade=CascadeType.ALL, orphanRemoval=true)
private Set<TextBooks> textBooks = new HashSet<TextBooks>();
//Having getters and setters for all above variables
}
TextBooks.java
class TextBooks {
#ManyToOne
#JoinColumn(name = "ID")
private Sample sample;
//Having getters and setters for all above variables
}
.hbm file
<class name="com.sample.Sample"
table="SAMPLE" >
<id name="id" column="ID" type="long">
<generator class="identity" />
</id>
<property column="TINY_URL" name="tinyUrl" />
<property column="DESCRIPTION" name="description" />
<set name="textBooks" inverse="true" cascade="all-delete-orphan">
<key column="ID" />
<one-to-many
class="com.text.TextBooks" />
</set>
</set>
</class>

Hibernate mapping: creating FK relation in existing db for join operations

I have an existing db that I cannot alter. There are two tables, one (A) with a PK and one (B) with a FK pointing to the PK of the first. The respective columns are named (A).page_id and (B).cl_from.
In Hibernate mapping i can set an id for the first, mapping the PK. I can also set a bag for the one-to-many relationship.
For the second, I don't need an id, but a many-to-one relationship. How can you set a many-to-one relationship without an id? I don't want to insert an id to the class..
I've tried to set a composite key but had no luck..
// The PK class
<class name="Words" table="PAGE">
<id name="id" column="PAGE_ID" />
<property name="text" column="PAGE_TITLE" />
<bag cascade="all-delete-orphan" inverse="true" lazy="false" name="wordPages">
<key column="PAGE_ID"/>
<one-to-many class="CategoryItems"/>
</bag>
</class>
// The FK class
<class name="CategoryItems" table="CATEGORYLINKS" >
<composite-id>
<key-many-to-one name="id" column="CL_FROM" />
</composite-id>
<property name="text" column="CL_TO" />
</class>
And my classes:
public class Words {
private Long id;
private String text;
private ArrayList wordPages;
// getters - setters
public class CategoryItems implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private String text;
//getters-setters
The latest error i get is: An association from the table CATEGORYLINKS refers to an unmapped class: java.lang.Long
should help with the following code:
public class CategoryItems implements Serializable
{
private static final long serialVersionUID = 1L;
private Words id;
private String text;
//getters-setters
}

Provided id of the wrong type hibernate

I am getting error:
org.hibernate.TypeMismatchException: Provided id of the wrong type for class BEntity. Expected: class BEntity, got class AEntity
public class BEntity implements Serializable{
#Id
#Column(name = "NUM")
private String num;
#Id
#Column(name = "INIT")
private String init;
#Column(name = "V_CNT")
private Integer vcnt;
//{{{some column omitted}}}//
}
public class AEntity implements Serializable{
#Id
#Column(name = "NUM")
private String num;
#Id
#Column(name = "INIT")
private String init;
#OneToOne
#PrimaryKeyJoinColumns({
#PrimaryKeyJoinColumn(name="NUM", referencedColumnName="NUM"),
#PrimaryKeyJoinColumn(name="INIT", referencedColumnName="INIT")
})
private BEntity bEntity;
}
HQL query:
String queryString = "FROM AEntity AS A " +
"LEFT JOIN A.bEntityAS B " +
"WHERE A.INIT||A.NUM IN (:carList) AND A.INIT IN (:initList) AND A.NUM IN (:numberList) " +
"AND B.TRUK_AXL_CNT > 0";
Hibernate gen-code
select aentity0_.NUMBER as NUMBER4_0_, aentity0_.INITIAL as INITIAL4_0_, bentity_p1_.NUMBER as NUMBER5_1_, bentity_p1_.INITIAL as INITIAL5_1_, aentity0_.V_CNT as VCNT3_4_0_, aentity0_.EIN as EIN4_0_, aentity0_.TYP as TYP5_4_0_, aentity0_.TRUK_CNT as TRUK6_4_0_, bentity_p1_.TRUK_AXL_CNT as TRUK3_5_1_ from USR.aentity aentity0_ left outer join USR.bentity_PRIMARY bentity_p1_ on aentity0_.NUMBER=bentity_p1_.NUMBER and aentity0_.INITIAL=bentity_p1_.INITIAL
where (aentity0_.INITIAL||aentity0_.NUMBER in (?,?,?))
and (aentity0_.INITIAL in (?,?,?))
and (aentity0_.NUMBER in (?, ?, ?))
and bentity_p1_.TRUK_AXL_CNT>0
When I run the code in SQL Explorer it works only running it in code cause the issue...
Looks like this is a defect in hibernate version 3.2.6 which is still not resolved. Came across this JIRA.
Having multiple #Id is supported by Hibernate but seems it fails under one to one mapping, suggested way of resolving this is to use single CompositeKey, which means you create a PK class
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class PKClass implements Serializable {
#Column(name = "NUM")
private String num;
#Column(name = "INIT")
private String init;
//gettter setter here
}
then in your Entity use this as the ID
public class BEntity implements Serializable{
#Id
private PKClass pkClass = null;
#Column(name = "V_CNT")
private Integer vcnt;
//{{{some column omitted}}}//
}
public class AEntity implements Serializable{
#Id
private PKClass pkClass = null;
#OneToOne
#PrimaryKeyJoinColumns({
#PrimaryKeyJoinColumn(name="NUM", referencedColumnName="NUM"),
#PrimaryKeyJoinColumn(name="INIT", referencedColumnName="INIT")
})
private BEntity bEntity;
}
I faced the same issue. I had two separate PK classes that had the same fields. So I removed one PK and used only one in the owner and child entity. This solved the problem.
I had the same problem.
Started situation
Primary key on master table
<composite-id name="id" class="model.E1Id">
<key-property name="taxpayerId" type="int">
<column name="TaxpayerID" />
</key-property>
<key-property name="year" type="int">
<column name="Year" />
</key-property>
</composite-id>
Primary key on detail table
<composite-id name="id" class="model.E1dataFromTaxPayerFolderId">
<key-property name="tid" type="int">
<column name="tID" />
</key-property>
<key-property name="year" type="int">
<column name="Year" />
</key-property>
</composite-id>
After repair
I change the class of detail table composite-id and i set the class of primary table like this:
<composite-id name="id" class="model.E1Id">
<key-property name="tid" type="int">
<column name="tID" />
</key-property>
<key-property name="year" type="int">
<column name="Year" />
</key-property>
</composite-id>
After that is necessary (if you have different names) to add in your primarykey class (in my case E1Id) the property tid (with getter and setter methods)

Returning Child IDs using JAXRS

I am running into an issue with JAXRS / JAXB including child IDs in JSON results when using #Produces. Below are portions of my code. Since we are using Hibernate, I'm abstracting the id into an AbstractEntity class.
POJOs:
#XmlRootElement
public abstract class AbstractEntity implements Serializable {
private Serializable id;
#XmlElement(type-Object.class)
#XmlSchemaType(name="anySimpleType")
public final Serializable getId() {
return this.id
}
public final Serializable setId(Serializable id) {
this.id = id;
}
}
#XmlRootElement
public class Parent extends AbstractEntity {
private String parentName;
private Child child;
#XmlElement
public String getParentName() {
return parentName;
}
#XmlElement
public Child getChild() {
return child;
}
}
#XmlRootElement
public class Child extends AbstractEntity {
private String childName;
#XmlElement
public String getChildName() {
return childName;
}
}
JAXRS Services:
#Path("/parent")
public class ParentService {
#GET
#Path("/get/{id}")
#Produces(MediaType.APPLICATION.JSON)
public Parent getById(#PathParam("id") Long id) {
Parent parent = hibernateDataController.getParentById(id);
if (parent== null)
throw new NotFoundException("GET: Parent" + id + " not found.");
return parent;
}
}
#Path("/child")
public class ChildService {
#GET
#Path("/get/{id}")
#Produces(MediaType.APPLICATION.JSON)
public Child getById(#PathParam("id") Long id) {
Child child = hibernateDataController.getChildById(id);
if (child == null)
throw new NotFoundException("GET: Child " + id + " not found.");
return child;
}
}
(Note: There is more code not shown, but the main parts are above)
My project is in Eclipse, using Maven, so I fire up Jetty: mvn jetty:run
This is where the problem starts. I can access the child POJO using:
http://myserver:8080/example/child/get/1 returns->
{
"id":{"#type":"xs:long","$":"1"},
"childName":"Bart Simpson"
}
But, when I access the parent POJO, the id of the child POJO is not returned:
http://myserver:8080/example/parent/get/1 returns ->
{
"id":{"#type":"xs:long","$":"1"},
"parentName":"Homer Simpson",
"child": {
"childName":"BartSimpson"
}
}
Notice that the ID of the child is not returned, just the childName. The GUI team that I am working with is using GWT and they are requesting that I include the ID of any children in the JSON results.
Any help in getting JAXRS / JAXB to return the ID within the child JSON would be greatly appreciated. Thanks for your time.
Matt
I found my solution to the missing child IDs this morning. It actually was not a JAXRS / JAXB issue, but caused by the Hibernate mapping files (yes, I still like to use a mapping file over annotations for Hibernate).
The Hibernate mapping file for the example file above would be:
<hibernate-mapping>
<class name="com.mycompany.Parent" table="PARENT">
<id name="id" type="java.lang.Long">
<column name="PARENT_ID" scale="0" />
<generator class="native" />
</id>
<property name="parentName" type="java.lang.String">
<column name="PARENT_NAME" />
</property>
<set name="children" inverse="true" lazy="true" table="CHILD" fetch="select">
<key>
<column name="CHILD_ID" />
</key>
<one-to-many class="com.mycompany.Child" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.mycompany.Child" table="CHILD">
<id name="id" type="java.lang.Long">
<column name="CHILD_ID" scale="0" />
<generator class="native" />
</id>
<property name="childName" type="java.lang.String">
<column name="CHILD_NAME" />
</property>
<many-to-one name="parent" type="com.mycompany.Child" fetch="select">
<column name="PARENT_ID" />
</many-to-one>
</class>
</hibernate-mapping>
The fix was to force Hibernate not to 'lazy load' the children. I changed:
<set name="children" inverse="true" **lazy="true"** table="CHILD" **fetch="select"**>
to:
<set name="children" inverse="true" lazy="false" table="CHILD" **fetch="join"**>
With the modified hibernate mapping files, the IDs came through the results of JAXRS:
{
"id":{"#type":"xs:long","$":"1"},
"parentName":"Homer Simpson",
"child": {
"id":{"#type":"xs:long","$":"1"},
"childName":"BartSimpson"
}
}
Hope this helps if someone else runs into this issue.

Categories

Resources