-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: many-to-many relations using many-to-one,one-to-many
PostPosted: Thu Feb 21, 2008 9:09 am 
Newbie

Joined: Thu Feb 21, 2008 8:39 am
Posts: 15
Hi,

I'm trying to use hibernate to map a many-to-many relation with some attributes in the shared table. Then I can't use the many-to-many relation, so i decided to use many-to-one and one-to-many relations with some attributes in the shared table.

The database is composed by tree tables, the first table called productes contains products ids and descriptions, the second table called clients contains the name and identifier of the clients and the last table create the M-N realtion between the clients and articles, this table is called CLIENTS_has_PRODUCTES.

the following code creates de database:

CREATE TABLE PRODUCTES (
ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
DESCRIPCIO Varchar(45) NULL,
PRIMARY KEY(ID)
);

CREATE TABLE CLIENTS (
ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
NOM Varchar(45) NULL,
PRIMARY KEY(ID)
);

CREATE TABLE CLIENTS_has_PRODUCTES (
CLIENTS_ID INTEGER UNSIGNED,
PRODUCTES_ID INTEGER UNSIGNED,
DATA Varchar(45) NULL,
PRIMARY KEY(CLIENTS_ID,PRODUCTES_ID),
FOREIGN KEY(CLIENTS_ID)
REFERENCES CLIENTS(ID),
FOREIGN KEY(PRODUCTES_ID)
REFERENCES PRODUCTES(ID)
);

the classes I use to map this database in java are:

public class ClientBean {
private int id=0;
private String nom;
private Set sells; //Objects Type hibernate_beans.Sells


//getters and setter
}

public class ArticleBean {
private int id=0;
private String descripcio;
private Set sells; //Objects Type hibernate_beans.Sells
private Sells s;
//getters and setters
}

the third class implements the shared table:

public class Sells{

private SellsID id;
private String data = null;
//getters and setters
}

as you can see this class contains another class as an ID, which is:

public class SellsID implements Serializable {
private ArticleBean itemId;
private ClientBean clientId;

public SellsID() {
this.itemId = null;
this.clientId = null;
}

public boolean equals(Object o) {
if (o instanceof SellsID) {
SellsID that = (SellsID)o;
return that.itemId == this.itemId && that.clientId == this.clientId;
} else {
return false;
}
}

public int hashCode() {
return itemId.hashCode() + clientId.hashCode();
}

//getters and setters
}

for mapping all this classes to hibernate I use the following 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">
<hibernate-mapping default-lazy="false">

<!--ClientBean-->
<class name="hibernate_beans.ClientBean" table="CLIENTS">
<id name="id" type="int" column="ID" unsaved-value="0">
<generator class="native"/>
</id>
<property name="nom" type="string" column="NOM"/>
<set name="sells" cascade="all" inverse="false" lazy="false">
<key column="CLIENTS_ID"/>
<one-to-many class="hibernate_beans.Sells"/>
</set>
</class>

<!--ArticleBean-->
<class name="hibernate_beans.ArticleBean" table="PRODUCTES">
<id name="id" type="int" column="ID" unsaved-value="0">
<generator class="native"/>
</id>
<property name="descripcio" type="string" column="DESCRIPCIO"/>
<set name="sells" cascade="all" inverse="false" lazy="false">
<key column="PRODUCTES_ID"/>
<one-to-many class="hibernate_beans.Sells"/>
</set>
</class>


<!--ClientBean-->
<class name="hibernate_beans.Sells" table="CLIENTS_has_PRODUCTES">
<composite-id class="hibernate_beans.SellsID" access="field" unsaved-value="any" >
<key-many-to-one name="itemId" class="hibernate_beans.ArticleBean" column="PRODUCTES_ID"/>
<key-many-to-one name="clientId" class="hibernate_beans.ClientBean" column="CLIENTS_ID"/>
</composite-id>

<property name="data" type="string" column="DATA"/>
</class>

</hibernate-mapping>

I have checked some examples from internet and also the hibernate project caveatemptor-0.9.5, which does something similar to what i'm trying to do.

I don't know if this code is correct, or if i understood something wrong form the web tutorial, but it does not do what i want.

When i try to execute the following lines to insert and element:

Session session = HibernateHelper.getSessionFactory().getCurrentSession();

session.beginTransaction();

ClientBean client = new ClientBean();
client.setNom("Albert");
session.saveOrUpdate(client);

ArticleBean article = new ArticleBean();
article.setDescripcio("cargols pel cap");
session.saveOrUpdate(article);


client.setSells(new HashSet());
article.setSells(new HashSet());

Sells sells = new Sells();
//sells.setClient(client);
//sells.setArticle(article);
sells.setData("data");


article.getSells().add(sells);
client.getSells().add(sells);

session.getTransaction().commit();

i get the following error:

Hibernate: insert into CLIENTS (NOM) values (?)
Hibernate: insert into PRODUCTES (DESCRIPCIO) values (?)
Exception in thread "main" org.hibernate.HibernateException: The class has no identifier property: hibernate_beans.Sells
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:174)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3596)
at org.hibernate.id.Assigned.generate(Assigned.java:28)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:99)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:218)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:131)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:122)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at hibernate_beans.provaHibernate.main(provaHibernate.java:44)

I exactlly don't understat what is happening here, i see that the client is correctly introduced to the database but not the product, about the exceptions java throws i do not understant exactly what it means, looks like if hibernate was trying to find a Sells class in Productes class???

Can anyone check if the mapping is correct?

I would appreciate any help or comment about what should and should't do?
I will also appreciate if anyone can show me where I can find a complet example of how to implement a many-to-many relation using many-to-one and one-to-many realtions.

Thanks in advance.

albert.sole


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 21, 2008 9:37 am 
Beginner
Beginner

Joined: Thu Dec 13, 2007 2:32 pm
Posts: 26
you are missing <id> element in Sells class mapping ...
( you have mentioned that in your <set> element mapping as you might have noticed, one-to-many class"Sells" ... blah ... blah


Let me know.

_________________
Regards,
Vyas, Anirudh


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 21, 2008 10:17 am 
Newbie

Joined: Thu Feb 21, 2008 8:39 am
Posts: 15
<class name="hibernate_beans.Sells" table="CLIENTS_has_PRODUCTES">
<composite-id class="hibernate_beans.SellsID" access="field" unsaved-value="any" >
<key-many-to-one name="itemId" class="hibernate_beans.ArticleBean" column="PRODUCTES_ID"/>
<key-many-to-one name="clientId" class="hibernate_beans.ClientBean" column="CLIENTS_ID"/>
</composite-id>
</class>

what i'm trying to do is to use the composite-id as id field(the composite-id will become the id), then I should not write id, do i'm i right?

what I'm trying to tell hibernate is that the composite-id is from class SellsID and this class has to fields itemId and clientId and both are classes.
I also have tryied to define this two elements, that now are classes, as primitive types (int) but when I write the line:

<key-many-to-one name="itemId" type="int" column="PRODUCTES_ID"/>

hibernate does not accept this mapping, type is not valid for tag key-many-to-one


I don't know what you mean with the second sentence of your answer.

Albert


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.