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
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.
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>
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
}
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)
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.