-->
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: Probleme mit case-insensitve bei PK/FK
PostPosted: Fri Oct 14, 2005 8:17 am 
Newbie

Joined: Fri Oct 14, 2005 7:34 am
Posts: 2
Hallo,

ich arbeite mit Hibernate 3.0 und MySQL 4.1.

MySQL arbeitet in Character Felder case-insensitiv. Über eine one-to-many Beziehung bin ich auf folgendes Problem gestoßen:

Eine einfache Klasse ohne Mapping und SQL:

Code:
public Example {
    private String pk;

    public String getPk() {
        return pk;
    }

    public void setPk(String pk)  {
        this.pk = pk;
    }
}



Folgender Code
Code:
Example example = (Example) session.get(Example.class, "abc");


initialisert das Object mit pk='abc' und dies unabhängig davon, ob der Datensatz in der Datenbank mit 'ABC' oder 'abc' gespeichert ist. Gleichermaßen erzeugt
Code:
Example example = (Example) session.get(Example.class, "ABC");

bei unveränderter Datenbasis ein Object mit pk='ABC'.

Ein Code mit Query
Code:
Query query = session.createQuery("FROM Example WHERE pk=:pk");
query.setString("pk", "ABC");
List list = query.list();
...

liefert hingegen das erwartete Ergbebnis, d.h. pk bildet exakt (case-sensitiv) den Wert aus der Datenbank ab.

Was in diesem einfachen Fall unbedeutend erscheint, wirkt sich bei einer Datenstruktur mit Beziehung (getestet mit many-to-one, gemappt mit set-Element) fatal aus. Session#get(Class clazz, Serializable id) liefert nur dann ein korrekt initialisiertes Object, inklusive der Objekte aus der Beziehung, wenn id exakt dem in der Datenbank gespeicherten PK entspricht (case-sensitiv). Das heißt die Child-Objekte werden case-sensitiv gesucht und initialisiert (bzw. eben nicht).

Die Query-Anweisung liefert das Object hingegen korrekt initialisiert, d.h. sucht und findet alle Objekte case-insensitiv, initialisiert sie korrekterweise aber case-sensitiv.

Gibt es eine Konfigurationmöglichkeit, evt. beim Mapping, welche das Verhalten der Session#get(Class clazz, Serializable id) Methode ändert.

Dank und Gruß

Kuno


Top
 Profile  
 
 Post subject: Probleme mit case-insensitve bei PK/FK
PostPosted: Mon Oct 17, 2005 5:14 am 
Newbie

Joined: Fri Oct 14, 2005 7:34 am
Posts: 2
Hallo,

zur weiteren Verdeutlichung hier ein lauffähiges Beispiel

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   <class name="beans.User" table="user">
      <id name="id" type="string">
         <column name="id" sql-type="char(10)" not-null="true" />
      </id>
      <property name="name">
         <column name="name" sql-type="char(50)" />
      </property>
   </class>
</hibernate-mapping>

Code:
public class Test {

   public static void main(String[] args) {
      
      Session session = HibernateUtil.getCurrentSession();
      Transaction tx = session.beginTransaction();
      User user = new User();
      user.setId("UserID");
      user.setName("Ein User fuer diverse Tests");
      session.save(user);
      tx.commit();
      HibernateUtil.closeSession();
      
      session = HibernateUtil.getCurrentSession();
      user = (User) session.get(User.class, "userid");
      System.out.println("GET      + userid = " + user.getId() + " - " + user.getName());
      HibernateUtil.closeSession();
      
      session = HibernateUtil.getCurrentSession();
      user = (User) session.get(User.class, "UserID");
      System.out.println("GET      + UserID = " + user.getId() + " - " + user.getName());
      HibernateUtil.closeSession();
      
      session = HibernateUtil.getCurrentSession();
      Criteria criteria = session.createCriteria(User.class);
      criteria.add(Expression.idEq("userid"));
      user = (User) criteria.uniqueResult();
      System.out.println("CRITERIA + userid = " + user.getId() + " - " + user.getName());
      HibernateUtil.closeSession();
      
      session = HibernateUtil.getCurrentSession();
      user = new User();
      user.setId("UserID");
      tx = session.beginTransaction();
      session.delete(user);
      tx.commit();
      HibernateUtil.closeSession();
   }
}

Ergibt als Ausgabe

Code:
GET      + userid = [b]userid[/b] - Ein User fuer diverse Tests
GET      + UserID = [b]UserID[/b] - Ein User fuer diverse Tests
CRITERIA + userid = [b]UserID[/b] - Ein User fuer diverse Tests


Auf die Darstellung des Verhaltens mit Beziehungen habe ich verzichtet. Die Methode session#refresh(Class clazz, Serializable id) hat das gleiche Verhalten wie session#get(Class clazz, Serializable id).

Praktisch kann ich beide Methoden bei case-insensitiven ID/PK nicht verwenden, da spätestens bei der Initilisierung von Child-Elementen des Parant-Objectes ein Fehler auftritt, da eine Verknüpfung über PK/FK fehl schlägt.

Gruß


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.