-->
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.  [ 2 posts ] 
Author Message
 Post subject: JPA @ManyToMany bidirect. Verbindungstab.-Daten auto dele.
PostPosted: Sun Mar 01, 2009 7:58 am 
Newbie

Joined: Sun Mar 01, 2009 7:10 am
Posts: 2
Guten Tag!

Ich habe folgendes Problem bei dem ich jetzt schon seit zwei Tagen festhänge. Beschreibung:
Ich habe eine Beziehung zwischen Personen und Rollen als ManyToMany bidirectional gemappt. Immer wenn ich mir die Rollen anzeigen lassen möchte werden die Daten der Verbindungstabelle automatisch gelöscht. Ich mache nur einen select und es wird automatsich ein delete gemacht.
Es sieht nach einer falsch konfigurierten Transaktion aus, nur habe ich Probleme die richtige Einstellung zu finden. Jeder Hinweis ist, egal wie kurz, Willkommen...

Wo muss ich ansetzen? Ist es Hibernates "dirty-checking" oder ist die Spring Transaktion nicht richtig eingestellt? Habe ich die Entitäten falsch gemappt?

Aufbau ist:
Beziehung m n
core_role<<----->>core_person

Es gibt eine Verbindungstabelle Namens core_person_role mit eigenem Primärschlüssel.

Folglich sieht das Ganze nun so aus:
core_role
--------
id
role

core_person_role
--------------
id
core_role(Primärschlüssel von core_role)
person_id(Primärschlüssel von core_person)

core_person
---------
id
name
login
..
...

Nun habe ich die Tabellen wie folgt verschaltet:
Code:
@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = false)
@Table(name="core_role")
public class Role {
...
    @ManyToMany(mappedBy="roles", fetch=FetchType.EAGER)
    private Collection<Person> persons;
...


Code:
@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = false)
@Table(name="core_person")
public class Person {
...
    @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.LAZY)
    @JoinTable(name="core_person_role", joinColumns={@JoinColumn(name="core_person")}, inverseJoinColumns={@JoinColumn(name="core_role")})
    private Collection<Role> roles;
...


In der Hoffnung die Sache in den Griff zu bekommen habe ich mal das dynamicUpdate auf beiden Seiten auf false gesetzt.

spring-config:
Code:
   <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" >
      <property name="persistenceUnitName" value="CorePersist" />
   </bean>
   
   <bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate" >
      <property name="entityManagerFactory" ref="entityManagerFactory" />
   </bean>
   
   <bean id="transferService" class="de.finarfin.dev.backend.businesslogic.service.impl.TransferService" />

   <bean id="genericDao" class="de.finarfin.dev.backend.persistence.generic.dao.impl.GenericDaoImpl" abstract="true">
      <property name="entityManagerFactory" ref="entityManagerFactory" />
   </bean>

   <bean id="personDao" class="de.finarfin.dev.backend.persistence.dao.impl.PersonDaoImpl" parent="genericDao" />

<bean id="roleDao" class="de.finarfin.dev.backend.persistence.dao.impl.RoleDaoImpl" parent="genericDao" />

   <bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
         <props>
             <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
      </property>
   </bean>

   <bean id="roleService" parent="txProxyTemplate">
      <property name="target">
         <bean class="de.finarfin.dev.backend.businesslogic.service.impl.RoleServiceImpl">
            <property name="dao" ref="roleDao" />
            <property name="transferService" ref="transferService" />
         </bean>
      </property>
   </bean>

   <bean id="serviceFactory" class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
      <property name="serviceLocatorInterface" value="de.finarfin.dev.backend.businesslogic.service.factory.ServiceFactory" />
   </bean>
   
   <bean id="personService" parent="txProxyTemplate">
      <property name="target">
         <bean class="de.finarfin.dev.backend.businesslogic.service.impl.PersonServiceImpl">
            <property name="dao" ref="personDao" />
            <property name="transferService" ref="transferService" />
         </bean>
      </property>
   </bean>


Ich habe als DB MySQL 5 im Einsatz mit Hibernate:
pom.xml:

Code:
      <dependency>
         <groupId>hibernate</groupId>
         <artifactId>hibernate</artifactId>
         <version>3.3.1.GA</version>
         <scope>compile</scope>
      </dependency>
      
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>ejb3-persistence</artifactId>
          <version>3.3.2.Beta1</version>
          <scope>compile</scope>
      </dependency>
      
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-annotations</artifactId>
          <version>3.4.0.GA</version>
          <scope>compile</scope>
      </dependency>
            
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-commons-annotations</artifactId>
          <version>3.3.0.ga</version>
          <scope>compile</scope>
      </dependency>       
      
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-entitymanager</artifactId>
          <version>3.4.0.GA</version>
          <scope>compile</scope>
      </dependency>


Log-Ausgabe der Stelle an der ich alle Rollen anfordere:
Code:
Hibernate:
    select
        role0_.id as id10_,
        role0_.role as role10_
    from
        core_role role0_
Hibernate:
    select
        persons0_.core_role as core2_1_,
        persons0_.core_person as core1_1_,
        person1_.id as id9_0_,
        person1_.day_of_birth as day2_9_0_,
        person1_.email as email9_0_,
        person1_.enabled as enabled9_0_,
        person1_.fax as fax9_0_,
        person1_.forename as forename9_0_,
        person1_.login as login9_0_,
        person1_.login_password as login8_9_0_,
        person1_.phone as phone9_0_,
        person1_.pre_fax as pre10_9_0_,
        person1_.pre_phone as pre11_9_0_,
        person1_.surname as surname9_0_
    from
        core_person_role persons0_
    left outer join
        core_person person1_
            on persons0_.core_person=person1_.id
    where
        persons0_.core_role=?
Hibernate:
    select
        persons0_.core_role as core2_1_,
        persons0_.core_person as core1_1_,
        person1_.id as id9_0_,
        person1_.day_of_birth as day2_9_0_,
        person1_.email as email9_0_,
        person1_.enabled as enabled9_0_,
        person1_.fax as fax9_0_,
        person1_.forename as forename9_0_,
        person1_.login as login9_0_,
        person1_.login_password as login8_9_0_,
        person1_.phone as phone9_0_,
        person1_.pre_fax as pre10_9_0_,
        person1_.pre_phone as pre11_9_0_,
        person1_.surname as surname9_0_
    from
        core_person_role persons0_
    left outer join
        core_person person1_
            on persons0_.core_person=person1_.id
    where
        persons0_.core_role=?
Hibernate:
    select
        address0_.core_person as core1_1_,
        address0_.core_address as core2_1_,
        address1_.id as id8_0_,
        address1_.city as city8_0_,
        address1_.house_number as house3_8_0_,
        address1_.postcode as postcode8_0_,
        address1_.street as street8_0_
    from
        core_person_address address0_
    left outer join
        core_address address1_
            on address0_.core_address=address1_.id
    where
        address0_.core_person=?
Hibernate:
    select
        persons0_.core_address as core2_1_,
        persons0_.core_person as core1_1_,
        person1_.id as id9_0_,
        person1_.day_of_birth as day2_9_0_,
        person1_.email as email9_0_,
        person1_.enabled as enabled9_0_,
        person1_.fax as fax9_0_,
        person1_.forename as forename9_0_,
        person1_.login as login9_0_,
        person1_.login_password as login8_9_0_,
        person1_.phone as phone9_0_,
        person1_.pre_fax as pre10_9_0_,
        person1_.pre_phone as pre11_9_0_,
        person1_.surname as surname9_0_
    from
        core_person_address persons0_
    left outer join
        core_person person1_
            on persons0_.core_person=person1_.id
    where
        persons0_.core_address=?
Hibernate:
    select
        persons0_.core_address as core2_1_,
        persons0_.core_person as core1_1_,
        person1_.id as id9_0_,
        person1_.day_of_birth as day2_9_0_,
        person1_.email as email9_0_,
        person1_.enabled as enabled9_0_,
        person1_.fax as fax9_0_,
        person1_.forename as forename9_0_,
        person1_.login as login9_0_,
        person1_.login_password as login8_9_0_,
        person1_.phone as phone9_0_,
        person1_.pre_fax as pre10_9_0_,
        person1_.pre_phone as pre11_9_0_,
        person1_.surname as surname9_0_
    from
        core_person_address persons0_
    left outer join
        core_person person1_
            on persons0_.core_person=person1_.id
    where
        persons0_.core_address=?
Hibernate:
    select
        address0_.core_person as core1_1_,
        address0_.core_address as core2_1_,
        address1_.id as id8_0_,
        address1_.city as city8_0_,
        address1_.house_number as house3_8_0_,
        address1_.postcode as postcode8_0_,
        address1_.street as street8_0_
    from
        core_person_address address0_
    left outer join
        core_address address1_
            on address0_.core_address=address1_.id
    where
        address0_.core_person=?
Hibernate:
    select
        address0_.core_person as core1_1_,
        address0_.core_address as core2_1_,
        address1_.id as id8_0_,
        address1_.city as city8_0_,
        address1_.house_number as house3_8_0_,
        address1_.postcode as postcode8_0_,
        address1_.street as street8_0_
    from
        core_person_address address0_
    left outer join
        core_address address1_
            on address0_.core_address=address1_.id
    where
        address0_.core_person=?
Hibernate:
    select
        persons0_.core_address as core2_1_,
        persons0_.core_person as core1_1_,
        person1_.id as id9_0_,
        person1_.day_of_birth as day2_9_0_,
        person1_.email as email9_0_,
        person1_.enabled as enabled9_0_,
        person1_.fax as fax9_0_,
        person1_.forename as forename9_0_,
        person1_.login as login9_0_,
        person1_.login_password as login8_9_0_,
        person1_.phone as phone9_0_,
        person1_.pre_fax as pre10_9_0_,
        person1_.pre_phone as pre11_9_0_,
        person1_.surname as surname9_0_
    from
        core_person_address persons0_
    left outer join
        core_person person1_
            on persons0_.core_person=person1_.id
    where
        persons0_.core_address=?
11:39:58,490 DEBUG [http-8080-2] org.springframework.orm.jpa.JpaTransactionManager: Initiating transaction commit
11:39:58,490 DEBUG [http-8080-2] org.springframework.orm.jpa.JpaTransactionManager: Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@3c177568]
Hibernate:
    delete
    from
        core_person_role
    where
        core_person=?
Hibernate:
    delete
    from
        core_person_role
    where
        core_person=?
Hibernate:
    delete
    from
        core_person_role
    where
        core_person=?


Vielen Dank!
finarfin


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 01, 2009 8:52 am 
Newbie

Joined: Sun Mar 01, 2009 7:10 am
Posts: 2
Das Thema hat sich dann doch auf einmal erledigt.

In meinem TransferService bilde ich die EntityBeans auf Dtos ab um einerseits die Trennung der Schichten zu gewährleisten und andererseits Lazy Loading zu umgehen. Dort ist mir ein programmatischer Fehler unterlaufen. Am falschen Objekt habe ich in einem bestimmten Fall gearbeitet.
Wenn ich aus Richtung der Rollen alle Personen hole sollen beim Erzeugen der PersonenDtos die Rollen am PersonenDto wiederum auf null gesetzt werden um einen unendlichen Loop zu vermeden.

Ich hatte leider am falschen Object die Personen auf null gesetzt. Anstatt am Dto die Personen auf null zu setzen hatte ich es an der Entität gemacht. Folglich haben sich die Werte innerhalb der Transaktion an der Entität geändert und Hibernate/Spring wollten diese Änderung persistieren.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.