-->
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.  [ 5 posts ] 
Author Message
 Post subject: <list> und one-to-many - Verständnisproblem!?
PostPosted: Wed Jun 28, 2006 5:16 am 
Newbie

Joined: Thu May 18, 2006 7:38 am
Posts: 10
Hallo!

Ich sitz grad an einen größeren Projekt und krieg einfach die Sache mit <list> nicht auf die Reihe. Hab mir mal ein kleines Sample gemacht und steh trotzdem an. Vielleicht kann mir jemand helfen!

Code:
<?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="at.jazz.database">
<class name="ItemPerson">
   <id name="id">
      <generator class="identity" />
   </id>
   <property name="firstname" type="string" length="50"/>
   <property name="lastname" type="string" length="50"/>
   
   <list name="phonenumbers">
      <key column="itempersonid"/>
      <list-index column="posn" />
      <one-to-many class="at.jazz.database.ItemPhone" />
   </list>
</class>
</hibernate-mapping>


Code:
<?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="at.jazz.database">
<class name="ItemPhone">
   <id name="id">
      <generator class="identity" />
   </id>
   <property name="phonenumber" type="string" length="50"/>

   <many-to-one name="itemPerson" class="at.jazz.database.ItemPerson" column="itempersonid"/>
   
</class>
</hibernate-mapping>


Code:
package at.jazz.database;

import java.util.ArrayList;
import java.util.List;

public class ItemPerson {
   private long id;
   private String firstname;
   private String lastname;
   private List<ItemPhone> phonenumbers = new ArrayList<ItemPhone>();
   
   public String getFirstname() {
      return this.firstname;
   }
   public void setFirstname(String firstname) {
      this.firstname = firstname;
   }
   public long getId() {
      return this.id;
   }
   public void setId(long id) {
      this.id = id;
   }
   public String getLastname() {
      return this.lastname;
   }
   public void setLastname(String lastname) {
      this.lastname = lastname;
   }
   public List<ItemPhone> getPhonenumbers() {
      return this.phonenumbers;
   }
   public void setPhonenumbers(List<ItemPhone> phonenumbers) {
      this.phonenumbers = phonenumbers;
   }
   public void addPhonenumber(ItemPhone itemPhone) {
      this.phonenumbers.add(itemPhone);
   }
   
   public ItemPerson() {
   }
   
   public ItemPerson(long id, String firstname, String lastname, List<ItemPhone> phonenumbers) {
      this.id = id;
      this.firstname = firstname;
      this.lastname = lastname;
      this.phonenumbers = phonenumbers;
   }   
}


Code:
package at.jazz.database;

public class ItemPhone {
   private long id;
   private String phonenumber;
   private ItemPerson itemPerson;
   
   public long getId() {
      return this.id;
   }
   public void setId(long id) {
      this.id = id;
   }
   public ItemPerson getItemPerson() {
      return this.itemPerson;
   }
   public void setItemPerson(ItemPerson itemPerson) {
      this.itemPerson = itemPerson;
   }
   public String getPhonenumber() {
      return this.phonenumber;
   }
   public void setPhonenumber(String phonenumber) {
      this.phonenumber = phonenumber;
   }
   
   public ItemPhone() {
   }

   public ItemPhone(long id, String phonenumber, ItemPerson itemPerson) {
      this.id = id;
      this.phonenumber = phonenumber;
      this.itemPerson = itemPerson;
   }
   
}


Schemaexport funktioniert einwandfrei und wie erwartet.
Nun möchte ich eine Person anlegen und dieser zwei Telefonnummern hinzufügen.

So funktioniert es und kommt mir ziemlich umständlich vor.

Code:
   public static void main(String[] args) {
      
      Configuration configuration = new Configuration().configure();
      
      SchemaExport export = new SchemaExport(configuration);
      export.create(false, true);
      
      SessionFactory sfactory = configuration.buildSessionFactory();
      Session mysession = sfactory.openSession();
      
      ItemPerson myperson = new ItemPerson();
      ItemPhone myphone1 = new ItemPhone();
      ItemPhone myphone2 = new ItemPhone();
      
      myperson.setFirstname("Marco");
      myperson.setLastname("Markl");

      myphone1.setPhonenumber("0699 10503050");
      myphone2.setPhonenumber("0720 738898");
      
      myperson.addPhonenumber(myphone1);
      myperson.addPhonenumber(myphone2);
      
      Transaction mytrans = mysession.beginTransaction();
      
      mysession.save(myperson);
      mysession.save(myphone1);
      mysession.save(myphone2);

      mytrans.commit();
   
      mysession.close();

   }

}


Kann ich die Liste mit den Telefonnummern nicht mit einem Befehl speichern? bzw. Automatisch mit ".save(myperson)"?

Danke für eure Hilfe!

Marco


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 28, 2006 4:24 pm 
Newbie

Joined: Wed Jun 28, 2006 2:57 pm
Posts: 5
Moin!

Hm, mal so von Newbie an den Grinsemann:
fehlt dir in deinem (ersten) Mapping evtl. die Tabellenangabe?
Quote:
<class name="ItemPerson">
<id name="id">
<generator class="identity" />
</id>
<property name="firstname" type="string" length="50"/>
<property name="lastname" type="string" length="50"/>

<list name="phonenumbers" table="ItemPhone">
...

Ich habe da die Doku durchforstet und beziehe mich da auf das letztes Beispiel in 6.2.4.

Dann ist die Assoziazion zur Tabelle ItemPhone klar und du kannst evlt. die
Code:
mysession.save(myphoneX)
Anweisungen weglassen.

Aber wie gesagt: kommt vom Newbie ... ;-)

Gruß,
Christoph


Top
 Profile  
 
 Post subject: Re: <list> und one-to-many - Verständnisproblem!?
PostPosted: Thu Jun 29, 2006 4:56 am 
Newbie

Joined: Mon Apr 24, 2006 5:56 am
Posts: 7
DerGrinsemann wrote:
Hallo!



Code:
<?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="at.jazz.database">
<class name="ItemPerson">
   <id name="id">
      <generator class="identity" />
   </id>
   <property name="firstname" type="string" length="50"/>
   <property name="lastname" type="string" length="50"/>
   
   <list name="phonenumbers">
      <key column="itempersonid"/>
      <list-index column="posn" />
      <one-to-many class="at.jazz.database.ItemPhone" />
   </list>
</class>
</hibernate-mapping>

...
Kann ich die Liste mit den Telefonnummern nicht mit einem Befehl speichern? bzw. Automatisch mit ".save(myperson)"?

Danke für eure Hilfe!

Marco


Hallo Marco...

Bin auch relativ neu mit Hibernate und hab daher die Syntax jetzt nicht im Kopf... es ist allerdings so, dass du hibernate sagen kannst, dass alle assoziierten objekte mitgespeichert werden sollen...

Das heißt: du musst explizit definieren, dass beim speichern eines ItemPerson-Objektes auch alle seine telefonnummern upgedated werden sollen. das machst du indem du beim eintrag <list name="phonenumbers" noch das attribute cascade anhängst

<list name="phonenumbers" cascade="save-update">

Danach sollte es einfach möglich sein ein sess.save(itemPerson) abzusetzen und damit auch die bereits vorhanden tels upzudaten, bzw die neu hinzugekommenen zu persistieren.

Die Frage ist, ob du das wirklich willst. Ich persönlich habe die Erfahrung gemacht, dass es (für meine Bedürfnisse) zielführender ist Hibernate so wenig Kontrolle wie möglich zu geben und dafür intelligente Business-Methoden zu implementieren. Aber geschmackssache.

PS: Nicht böse sein, wenns doch nicht geht, aber wie gesagt: ich verwende es nie.

PPS: @ Christoph... die Beziehung zur Tabelle ItemsPhone sollte sowieso klar sein, da wenn keine explizite Table angegeben wird, die Forderung Klassenname == Tabellenname angenommen wird


Top
 Profile  
 
 Post subject: Re: <list> und one-to-many - Verständnisproblem!?
PostPosted: Thu Jun 29, 2006 2:22 pm 
Newbie

Joined: Wed Jun 28, 2006 2:57 pm
Posts: 5
dirtyharri wrote:
PPS: @ Christoph... die Beziehung zur Tabelle ItemsPhone sollte sowieso klar sein, da wenn keine explizite Table angegeben wird, die Forderung Klassenname == Tabellenname angenommen wird


Ich war mir da aufgrund der Doku nicht so sicher. Im Beispiel vom Tutorial wird aber, wie du es sagst, die Referenztabelle auch nicht explizit angegeben. In dem Beispiel werden aber aus Set's und keine List's verwendet.

Danke jedenfalls für den Hinweis.

Gruß,
Christoph


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 27, 2006 10:53 am 
Regular
Regular

Joined: Thu Jan 27, 2005 8:58 am
Posts: 80
Ich habe in dieser Beziehung noch ein weiteres Problem. Wenn ich nun die Collection habe, bestehende Objekte verändere und neue hinzufüge möchte ich sie mit einem Befehl speichern (was ja auch über Cascade="save-update" möglich ist. Ich bekomme auch den Output, dass ein entsprechender Update und Insert Befehl losgeshcickt wurden. Im Anschluss daran versucht Hibernate aber alle Spalten MaId und VonDat der Tabelle die zu dem Mitarbeiter gehören auf NULL zu setzen. WARUM!?! Dies kann natürlich nicht funktionieren, da sie in der Datenbank und wie im Mapping zu sehen als not-null="true" gekennzeichent sind. Ich hoffe Ihr habt ne Erklärung für mich ^^

hier nun mein Code:
Mitarbeiter.hbm.xml
Code:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
                            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration.                   -->
<!-- Created Tue Feb 15 16:12:02 CET 2005                         -->
<hibernate-mapping package="de.myCompany.model" default-lazy="false">

    <class name="Mitarbeiter" table="mitarbeiter">
        <id name="maId" column="ma_id" type="java.lang.Integer">
            <generator class="assigned"/>
        </id>

        <property name="titel" column="titel" type="java.lang.String" />
        <property name="vorname" column="vorname" type="java.lang.String"  not-null="true" />
        <property name="nachname" column="nachname" type="java.lang.String"  not-null="true" />
               
        <list name="wochenarbeitsZeiten" table="mitarbeiter_wochen_arb_std" lazy="true" cascade="save-update">
           <key column="ma_id" />
           <list-index column="von_dat" />
           <one-to-many class="MitarbeiterWochenArbStd" />
        </list>
    </class>
</hibernate-mapping>


MitarbeiterWochenArbStd.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
                            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration.                   -->
<!-- Created Thu Jul 27 12:11:15 CEST 2006                         -->
<hibernate-mapping package="de.myCompany.model" default-lazy="false">

    <class name="MitarbeiterWochenArbStd" table="mitarbeiter_wochen_arb_std">
        <id name="mwId" column="mw_id" type="java.lang.Integer">
            <generator class="native"/>
        </id>

        <property name="wochenArbStd" column="wochen_arb_std" type="java.lang.Float"  not-null="true" />
        <property name="vonDat" column="von_dat" type="java.util.Date"  not-null="true" />
        <property name="bisDat" column="bis_dat" type="java.util.Date" />
        <property name="letzteAenderung" column="letzte_aenderung" type="java.util.Date"  not-null="true" />
        <property name="bemerkung" column="bemerkung" type="java.lang.String" />

        <many-to-one name="mitarbeiter" column="ma_id" class="Mitarbeiter"  not-null="true" />
        <many-to-one name="bearbeiter" column="bearbeiter" class="Mitarbeiter" not-null="true" />
    </class>
   
</hibernate-mapping>


Quelltext
Code:
public static void main(String[] args){
      de.myCompany.model.Mitarbeiter m  = null;
      try{
         org.hibernate.Session s = de.myCompany.hibernate.SessionFactory.currentSession();
         org.hibernate.Query q = s.createQuery("from Mitarbeiter m where m.maId=71");
          m = (de.fourthproject.controlling.integration.model.Mitarbeiter)q.uniqueResult();
          if(m!=null){
m.setWochenarbeitsZeiten(s.createQuery("from MitarbeiterWochenArbStd m where m.mitarbeiter=71").list());
               java.util.List l1 = m.getWochenarbeitsZeiten();
               System.out.println();
            de.myCompany.model.MitarbeiterWochenArbStd mw = (de.myCompany.model.MitarbeiterWochenArbStd) m.getWochenarbeitsZeiten().get(0);
            mw.setBisDat(new java.util.Date());
            mw = new de.myCompany.model.MitarbeiterWochenArbStd();
            mw.setBearbeiter(m);
            mw.setBemerkung("");
            mw.setLetzteAenderung(new java.util.Date());
            mw.setMitarbeiter(m);
            mw.setVonDat(new java.util.Date());
            mw.setWochenArbStd(new java.lang.Float(30));
            m.getWochenarbeitsZeiten().add(mw);
            org.hibernate.Transaction trx = s.beginTransaction();
            trx.begin();
            s.update(m);
            trx.commit();
         }
      }
      catch(org.hibernate.HibernateException e ){   
      System.out.println(e.getMessage());
      System.out.println(e.getCause());
      e.printStackTrace();
      }
      finally{
         try{
            de.myCompany.hibernate.SessionFactory.closeSession();
         }
         catch(org.hibernate.HibernateException e ){
            
            e.printStackTrace();
         }   
      }

   }


und die Fehlerausgabe:
Code:
Hibernate: insert into mitarbeiter_wochen_arb_std (wochen_arb_std, von_dat, bis_dat, letzte_aenderung, bemerkung, ma_id, bearbeiter) values (?, ?, ?, ?, ?, ?, ?) select scope_identity()
Hibernate: update mitarbeiter_wochen_arb_std set wochen_arb_std=?, von_dat=?, bis_dat=?, letzte_aenderung=?, bemerkung=?, ma_id=?, bearbeiter=? where mw_id=?
[b]Hibernate: update mitarbeiter_wochen_arb_std set ma_id=null, von_dat=null where ma_id=?[/b]
could not delete collection:
[de.myCompany.model.Mitarbeiter.wochenarbeitsZeiten#71]
java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]Der Wert NULL kann in die von_dat-Spalte, mitarbeiter_wochen_arb_std-Tabelle, nicht eingefügt werden. Die Spalte lässt NULL-Werte nicht zu. Fehler bei UPDATE.
org.hibernate.exception.GenericJDBCException: could not delete collection: [de.myCompany.model.Mitarbeiter.wochenarbeitsZeiten#71]
   at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:91)
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:79)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:980)
   at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:28)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1007)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:354)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at de.myCompany.service.MitarbeiterService.main(MitarbeiterService.java:2718)
Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]Der Wert NULL kann in die von_dat-Spalte, mitarbeiter_wochen_arb_std-Tabelle, nicht eingefügt werden. Die Spalte lässt NULL-Werte nicht zu. Fehler bei UPDATE.
   at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source)
   at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source)
   at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processErrorToken(Unknown Source)
   at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReplyToken(Unknown Source)
   at com.microsoft.jdbc.sqlserver.tds.TDSRPCRequest.processReplyToken(Unknown Source)
   at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReply(Unknown Source)
   at com.microsoft.jdbc.sqlserver.SQLServerImplStatement.getNextResultType(Unknown Source)
   at com.microsoft.jdbc.base.BaseStatement.commonTransitionToState(Unknown Source)
   at com.microsoft.jdbc.base.BaseStatement.postImplExecute(Unknown Source)
   at com.microsoft.jdbc.base.BasePreparedStatement.postImplExecute(Unknown Source)
   at com.microsoft.jdbc.base.BaseStatement.commonExecute(Unknown Source)
   at com.microsoft.jdbc.base.BaseStatement.executeUpdateInternal(Unknown Source)
   at com.microsoft.jdbc.base.BasePreparedStatement.executeUpdate(Unknown Source)
   at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
   at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:970)


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