# Hibernate: many-to-many funktioniert noch nicht ganz



## rapthor (31. Okt 2006)

Hallo,

ich habe eine *Tabelle "Users" und "Groups", sowie "UserGroups", um Benutzer einer oder mehreren Gruppen zuzuordnen*.

Für alle 3 Tabellen habe ich Java-Objekte mit *gettern und settern *erstellt. "User" und "Group" enthalten jeweils zusätzlich zu ihren Standardattributen wie Name, Beschreibung noch jeweils getter und setter für ein *"Set" aus "Group"s bzw. "User"s.*

Sobald ich jedoch noch einen Benutzer einer Gruppe zuordnen möchte, fügt Hibernate den Benutzer NICHT zur Gruppe hinzu, meckert aber auch nicht rum.

Kann mir wer helfen?

Ich wollte den Vorgang wie folgt bewerkstelligen:


```
public void putUserIntoGroup()
	{
		Session session = SessionFactoryUtils.getSession(sessionFactory, true);
		TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));		
				
		
		IUserDAO userDAO = (IUserDAO)beanFactory.getBean("userDAO");
		User theUser= userDAO.getById(1);
		
		IGroupDAO groupDAO = (IGroupDAO)beanFactory.getBean("groupDAO");
		Group theGroup= groupDAO.getById(4);
		
                                // ist das notwendiug??
                                // würde ich damit nicht alle einträge
                                // zwischen dem benutzer und seinen
                                // gruppen löschen?
		// thisone.setSubscribed_groups(new HashSet<Group>());
		thisone.getSubscribed_groups().add(theGroup);
		
                                // ... hier die gleiche frage
		//thisgroup.setParticipating_users(new HashSet<User>());
		thisgroup.getParticipating_users().add(theUser);
		
                                // hier sollte hibernate den aktualisierten
                                // benutzer speichern (und die datenbank aktualisieren)
                                // aber leider hat diese Zeile KEINE WIRKUNG !!
                                // die Methode "save" macht das: getHibernateTemplate().saveOrUpdate(user);		                userDAO.save(theUser);

                                // aufgrund von "cascade=all" nicht notwendig ??
		//groupDAO.save(theGroup);
		
		TransactionSynchronizationManager.unbindResource(sessionFactory);
		SessionFactoryUtils.releaseSession(session, sessionFactory);		
	}
```



*Es folgen alle relevanten Mapping-Dateien und Java-Klassen-Codes:*

User.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">
<hibernate-mapping package="de.tfhberlin.eclipsophone.server.beans" auto-import="true">
  <class name="User" table="Users">
    <id name="id" column="id" type="long" unsaved-value="0">
      <generator class="native"/>
    </id>
    <property name="name" column="name" type="string"/>
    <property name="password" column="password" type="string"/>
    <set name="subscribed_groups" outer-join="true" table="UserGroups" cascade="all">
    	<key column="user_ID"/>
		<many-to-many class="Group" column="group_ID"/>
    </set>
  </class>  
    
</hibernate-mapping>
```

Group.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">
<hibernate-mapping package="de.tfhberlin.eclipsophone.server.beans" auto-import="true">
  <class name="Group" table="Groups">
    <id name="id" column="id" type="long" unsaved-value="0">
      <generator class="native"/>
    </id>
    <property name="name" column="name" type="string"/>
    <property name="description" column="description" type="string"/>
	<set name="participating_users" outer-join="true" inverse="true" table="UserGroups">
    	<key column="group_ID"/>
    	<many-to-many class="User" column="user_ID"/>
	</set>    
  </class>
</hibernate-mapping>
```

UserGroup.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">
<hibernate-mapping package="de.tfhberlin.eclipsophone.server.beans" auto-import="true">
  <class name="UserGroup" table="UserGroups">
    <id name="id" column="id" type="long" unsaved-value="0">
      <generator class="native"/>
    </id>
    <property name="user_ID" column="user_ID" type="long"/>
    <property name="group_ID" column="group_ID" type="long"/>
  </class>
</hibernate-mapping>
```

*Es folgen die Klassen dazu:*

User.java:

```
package de.tfhberlin.eclipsophone.server.beans;

import java.util.Iterator;
import java.util.Set;

public class User
{
	private String name;
	private String password;
	private long id;	
	private Set<Group> subscribed_groups;
	
	public User()
	{
		
	}

	public long getId()
	{
		return id;
	}

	public void setId(long id)
	{
		this.id = id;
	}	
	
	public String getName()
	{
		return name;
	}	
	
	public void setName(String name)
	{	
		this.name = name;
	}
	
	public String getPassword()
	{
		return password;
	}
	
	public void setPassword(String password)
	{
		this.password = password;
	}

	public Set<Group> getSubscribed_groups() {
		return subscribed_groups;
	}

	public void setSubscribed_groups(Set<Group> subscribed_groups) {
		this.subscribed_groups = subscribed_groups;
	}
	
	public String toString()
	{
		StringBuffer sb = new StringBuffer();
		sb.append("User {id=" + id + ", name=" + name + ", groups={");
		
		for (Iterator<Group> i = subscribed_groups.iterator(); i.hasNext(); )
			sb.append("(" + i.next() + "), ");
		
		if (subscribed_groups.size() > 0)		
			sb.delete(sb.length()-2, sb.length());
		
		sb.append("}}");
		
		return sb.toString();
	}
}
```

Group.java:

```
package de.tfhberlin.eclipsophone.server.beans;

import java.util.Set;

public class Group
{
	private long id;
	private String name;
	private String description;
	private Set<User> participating_users;
	
	public Group()
	{
		
	}
	
	public long getId()
	{
		return id;
	}

	public void setId(long id)
	{
		this.id = id;
	}
	
	public String getName()
	{
		return name;
	}
	
	public void setName(String name)
	{	
		this.name = name;
	}
	
	public String getDescription()
	{
		return description;
	}
	
	public void setDescription(String description)
	{
		this.description = description;
	}
	
	public Set<User> getParticipating_users() {
		return participating_users;
	}

	public void setParticipating_users(Set<User> participating_users) {
		this.participating_users = participating_users;
	}	
	
	public String toString()
	{
		return "Group {id=" + id + ", name=" + name + ", description=" + description + "}";
	}	
}
```

UserGroup.java:

```
package de.tfhberlin.eclipsophone.server.beans;

public class UserGroup
{
	private long user_ID;
	private long group_ID;
	private long id;
	
	public UserGroup()
	{
		
	}
	
	public long getId()
	{
		return id;
	}

	public void setId(long id)
	{
		this.id = id;
	}	
	
	public long getUser_ID()
	{
		return user_ID;
	}
	
	public void setUser_ID(long user_ID)
	{	
		this.user_ID = user_ID;
	}
	
	public long getGroup_ID()
	{
		return group_ID;
	}
	
	public void setGroup_ID(long group_ID)
	{
		this.group_ID = group_ID;
	}
	
	public String toString()
	{
		return "UserGroup {id=" + id + ", userid=" + user_ID + ", groupid=" + group_ID + "}";
	}	
}
```


----------



## KSG9|sebastian (1. Nov 2006)

was sagen die hibernate logs? show_sql auf true setzen und schauen was hibernate abfeuert und was nicht.


----------



## rapthor (3. Nov 2006)

Mein Problem hing mit der Verwendung der SessionFactory zusammen. Änderungen der "UserGroups" wurden aus irgendeinem Grund nicht übernommen. Aber mit der korrekten Initialisierung einer Transaktion funktionierte es schließlich.


----------

