-->
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: Bulk insert troubles (SOLVED with extra join)
PostPosted: Sun Aug 07, 2011 2:16 am 
Newbie

Joined: Sun Aug 07, 2011 1:39 am
Posts: 1
I'm trying to use bulk insert as per 13.4. DML-style operations of the manual.
My case wasn't described in this chapter so i started to experiment.
The goal is simple: I have three tables:

Code:
create table a (id int primary key);
create table b(id int primary key);
create table c(id int primary key, a_id int references a, b_id int references b);


I'm already know the A primary key and trying to fill the C with all values from B
like in the last SQL below (suppose i dont know the B's rows, second
insert is just to fill B with some data):

Code:
insert into A (id) values (1);
insert into B (id) values (1);
insert into C (id, a_id, b_id) select 1, 1, b.id from B b;


First (naive) attempt:
Code:
Query q = session.createQuery("insert into C (a, b) select :a, b from B");
q.setParameter("a", a1);
q.executeUpdate();


Not working, and gives me:

org.hibernate.QueryException: number of select types did not match those for insert [insert into C (a, b) select :a, b from Main$B]


Probably I can understand - the actual type of the ':a' is not known (why?).

[Main$B: my classes in test case are nested inside the Main class. See listing at the bottom.]

Second attempt (with extra join which is redundant and can dergade the performance):
Code:
Query q = session.createQuery("insert into C (a, b) select a, b from A a, B b where a = :a");
q.setParameter("a", a1);
q.executeUpdate();


Not working, gives me (a little strange) error:


org.postgresql.util.PSQLException: ERROR: column reference "id" is ambiguous


When debug is turned on i can see why:

could not execute update query [insert into C ( id, a_id, b_id ) select nextval ('hibernate_sequence'), main_a0_.id as col_0_0_, main_b1_.id as col_1_0_ from A main_a0_ cross join B main_b1_ where id=?]

Last attemp is working.
Code:
Query q = session.createQuery("insert into C (a, b) select a, b from A a, B b where a.id = :a");
q.setParameter("a", a1.getId());
q.executeUpdate();


This may help to someone who trying to achieve the similar goal.
Hibernate 3.6.6.Final, PostgreSQL 8.4.8, JDK jdk1.6.0_26 (Win7).

Below is full listing of the test case:

Code:

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

import javax.persistence.*;

public class Main {

    public static void main(final String[] args) throws Exception {

        Configuration config = new Configuration();
        config.addAnnotatedClass(A.class);
        config.addAnnotatedClass(B.class);
        config.addAnnotatedClass(C.class);

        SessionFactory factory = config.configure("hibernate.cfg.xml").buildSessionFactory();
        Session session = factory.openSession();
        Transaction t;

        {
            t = session.beginTransaction();
            session.createQuery("delete from C").executeUpdate();
            session.createQuery("delete from B").executeUpdate();
            session.createQuery("delete from A").executeUpdate();
            t.commit();
        }

        A a1;
        B b1;

        try {
            t = session.beginTransaction();

            a1 = new A();
            session.save(a1);

            b1 = new B();
            session.save(b1);

            t.commit();
        } catch (Exception ex) {
            t.rollback();
            throw ex;
        }

        try {
            t = session.beginTransaction();
            Query q = session.createQuery("insert into C (a, b) select :a, b from B");
            q.setParameter("a", a1);
            q.executeUpdate();
            System.out.println("1. WORKING");
            t.commit();
        } catch (Exception ex) {
            t.rollback();
            System.err.println("1. not working");
            Throwable error = ex;
            while (error != null) {
                error.printStackTrace();
                error = error.getCause();
            }
        }

        try {
            t = session.beginTransaction();
            Query q = session.createQuery("insert into C (a, b) select a, b from A a, B b where a = :a");
            q.setParameter("a", a1);
            q.executeUpdate();
            System.out.println("2. WORKING");
            t.commit();
        } catch (Exception ex) {
            t.rollback();
            System.err.println("2. not working");
            Throwable error = ex;
            while (error != null) {
                error.printStackTrace();
                error = error.getCause();
            }
        }

        try {
            t = session.beginTransaction();
            Query q = session.createQuery("insert into C (a, b) select a, b from A a, B b where a.id = :a");
            q.setParameter("a", a1.getId());
            q.executeUpdate();
            System.out.println("3. WORKING");
            t.commit();
        } catch (Exception ex) {
            t.rollback();
            System.err.println("3. not working");
            Throwable error = ex;
            while (error != null) {
                error.printStackTrace();
                error = error.getCause();
            }
        }

        session.flush();
        session.close();

    }

    @Entity(name = "A")
    public static class A {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        long id;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

    }

    @Entity(name = "B")
    public static class B {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        long id;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

    }

    @Entity(name = "C")
    public static class C {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        long id;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        @ManyToOne
        A a;

        public A getA() {
            return a;
        }

        public void setA(A a) {
            this.a = a;
        }

        @ManyToOne
        B b;

        public B getB() {
            return b;
        }

        public void setB(B b) {
            this.b = b;
        }

    }

}



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.