-->
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.  [ 1 post ] 
Author Message
 Post subject: One-to-One, scalars and nulls
PostPosted: Fri May 26, 2006 9:14 am 
Newbie

Joined: Thu May 25, 2006 11:55 am
Posts: 2
Hi.
Hibernate 3.1.3 appears to have a problem when returning scalars in combination with a one-to-one relationship fetch.

Hibernate 3.1.3
Postgres 8.1.2
Java 1.5.0_06

Given that "a" is a table whose id is reflected in table "b" as a PRIMARY FOREIGN KEY.
Mapping a->b and b->a with the appropriate "one-to-one" mappings (I hope), then

Code:
select a, b from A a join a.b b

returns a and b instances correctly..

However: this is where I see the problem

Code:
select a, b, 'Some scalar' from A a join a.b b

returns a and the scalar correctly, but NULLS out b!


Please note that I have no idea if this problem occurs using other relation types or in any other circumstances



Here's my schema:

Code:
-- Postgres 8.1.2

drop database problem;
create database problem;

\c problem

create schema problem;

-- primary..
create table problem.a (id int, amessage varchar, primary key (id));

-- PFK #1..
create table problem.b (id int, bmessage varchar, primary key (id));

-- PFK #2..
create table problem.c (id int, cmessage varchar, primary key (id));


-- PFK constraints..
alter table problem.b add foreign key (id) references problem.a (id) on update restrict on delete restrict;
alter table problem.c add foreign key (id) references problem.a (id) on update restrict on delete restrict;


-- data..
insert into problem.a values (1, 'a-1');
insert into problem.a values (2, 'a-2');
insert into problem.a values (3, 'a-3');

insert into problem.b values (1, 'b-1');
insert into problem.b values (2, 'b-2');
insert into problem.b values (3, 'b-3');

insert into problem.c values (1, 'c-1');
insert into problem.c values (2, 'c-2');
insert into problem.c values (3, 'c-3');


And my mappings..

Code:
<hibernate-mapping package="problem.bean">

    <class name="A" schema="problem" table="a" dynamic-update="false" dynamic-insert="false" select-before-update="false">

        <id name="id" column="id" type="java.lang.Integer" unsaved-value="null"/>
        <property name="amessage" type="java.lang.String"/>

        <one-to-one name="B" class="B" constrained="false"/>

   </class>


    <class name="B" schema="problem" table="b" dynamic-update="false" dynamic-insert="false" select-before-update="false">

        <id name="id" column="id" type="java.lang.Integer" unsaved-value="null"/>
        <property name="bmessage" type="java.lang.String"/>

        <one-to-one name="A" class="A" constrained="true"/>

   </class>

</hibernate-mapping>




And the test class and beans..

Code:
package problem;

import java.io.File;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/*
   Hibernate 3.1.3
   one-to-one vs. scalar problem
*/

class Test
{
    private Configuration cfg;
    private SessionFactory sessionFactory;
    private Session session;
   
    public Test()
    {       
    }
   
    public void go()
    {
      say("\n\n\n\n\n\n");
        say("Testing one-to-one vs. scalar problem");
       
        say(".................................................................");
        say(" FIRST: Select a, b with generic joins, returning all 3..");
        say(".................................................................");
        say("");
       
        String hql = "select a, b from A a join a.B b";
        say("HQL is \"%s\"", hql);
        Query q = session.createQuery(hql);
        List l = q.list();
       
        dump(l);
       
        say("\n\n\n");
           
        say(".................................................................");
        say(" NEXT: Select a, b AND SCALAR.. (B IS SET TO NULL!!)");
        say(".................................................................");
        say("");
       
        hql = "select a, b, 'Scalar value' as x from A a join a.B b";
        say("HQL is \"%s\"", hql);
        q = session.createQuery(hql);
        l = q.list();
       
        dump(l);

        say(".................................................................");
        say(" FINALLY: Select SCALAR, a and b.. (postion of scalar makes no difference)");
        say(".................................................................");
        say("");
       
        hql = "select 'Scalar value', a, b from A a join a.B b";
        say("HQL is \"%s\"", hql);
        q = session.createQuery(hql);
        l = q.list();
       
        dump(l);
       
        say("");
        say("======================================================================");
        say(" As you can see, the one-to-one relation from A to B combined with a scalar return sets B to NULL");
        say("======================================================================");
        say("");
    }
   
    private void dump(List l)
    {
        int idx = 0;
        for (Object row : l)
        {
            System.out.printf("%2d: |", idx++);
            for (Object item : (Object[])row)
                System.out.printf(" %s |", item);           
            System.out.printf("\n");
        }       
    }
   
   
    public void initialiseHibernate()
    {
        try
        {
            cfg = new Configuration();
       
            cfg.configure(new File("hibernate.cfg.xml"));
            cfg.addFile(new File("problem.hbm.xml"));
           
            sessionFactory = cfg.buildSessionFactory();           
           
            session = sessionFactory.openSession();
        }
        catch (Exception ex)
        {
            error("Error during Hibernate initialisation", ex);
        }
               
    }
   
    private void say(String message, Object... args)
    {
        System.out.printf(message + "\n", args);
    }
   
    private void error(String message, Throwable t, Object... args)
    {
        System.err.printf(message + "\n", args);
        if (t != null)
            t.printStackTrace();
    }

   
    public static void main(String[] args)
    {
        Test test = new Test();
        test.initialiseHibernate();
        test.go();
    }
   
}




Code:
package problem.bean;

class A
{
   private int id;
   public int getId() { return id; }
   public void setId(int id ) { this.id = id; }

   private String amessage;
   public String getAmessage() { return amessage; }
   public void setAmessage(String amessage) { this.amessage = amessage; }

   private B b;
   public B getB() { return b; }
   public void setB(B b) { this.b = b; }
   
    public String toString()
    {
        return String.format("[A: id=%s message=%s]", id, amessage);
    }

}




Code:
package problem.bean;

class B
{
   private int id;
   public int getId() { return id; }
   public void setId(int id ) { this.id = id; }

   private String bmessage;
   public String getBmessage() { return bmessage; }
   public void setBmessage(String bmessage) { this.bmessage = bmessage; }
   
   private A a;
   public A getA() { return a; }
   public void setA(A a) { this.a = a; }

    public String toString()
    {
        return String.format("[B: id=%s message=%s]", id, bmessage);
    }

}





And the output

Code:
Testing one-to-one vs. scalar problem
.................................................................
FIRST: Select a, b with generic joins, returning all 3..
.................................................................

HQL is "select a, b from A a join a.B b"
0: | [A: id=1 message=a-1] | [B: id=1 message=b-1] |
1: | [A: id=2 message=a-2] | [B: id=2 message=b-2] |
2: | [A: id=3 message=a-3] | [B: id=3 message=b-3] |




.................................................................
NEXT: Select a, b AND SCALAR.. (B IS SET TO NULL!!)
.................................................................

HQL is "select a, b, 'Scalar value' as x from A a join a.B b"
0: | [A: id=1 message=a-1] | null | Scalar value |
1: | [A: id=2 message=a-2] | null | Scalar value |
2: | [A: id=3 message=a-3] | null | Scalar value |
.................................................................

FINALLY: Select SCALAR, a and b.. (postion of scalar makes no difference)
.................................................................

HQL is "select 'Scalar value', a, b from A a join a.B b"
0: | Scalar value | [A: id=1 message=a-1] | null |
1: | Scalar value | [A: id=2 message=a-2] | null |
2: | Scalar value | [A: id=3 message=a-3] | null |

======================================================================
As you can see, the one-to-one relation from A to B combined with a scalar return sets B to NULL
======================================================================



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

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.