-->
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: Join with non Primary-key column, hibernate bug?
PostPosted: Tue Jan 08, 2013 6:06 am 
Newbie

Joined: Tue Jan 08, 2013 5:52 am
Posts: 2
I've been searching for hours and hours on each possible forum on the Internet a solution to the following problem.
Can someone please help?
I have two tables:
Code:
CREATE TABLE `customer` (
  `id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  `passnr_fk` int(11) DEFAULT NULL,
   PRIMARY KEY (`id`)
)


Code:
CREATE TABLE `passport` (
  `pass_id` int(11) NOT NULL,
  `pass_nr` int(11) NOT NULL,
  `color` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`pass_id`),
  UNIQUE KEY `pass_nr_UNIQUE` (`pass_nr`)
)


And I'm trying to join passnr_fk from Customer with pass_nr of Password which is not the primary Key.
This is OneToOne relationship.

HibernateUtil.java
Pay attention that the code is a bit different from the official Hibernate documentation which sadly enough uses deprecated code...
Code:
import hibernate.test.Customer;
import hibernate.test.Passport;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
           Configuration config = new Configuration();
           config.addAnnotatedClass(Customer.class);
           config.addAnnotatedClass(Passport.class);
           config.configure("/resources/hibernate.cfg.xml");
           ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
            return config.buildSessionFactory(serviceRegistry);
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}


hibernate.cfg.xml
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

    </session-factory>

</hibernate-configuration>


Customer.java
Code:
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;


@Entity
public class Customer {
   
   private Long id;
   private String name;
   private Passport passport;

   @Id
   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
      
   @OneToOne()
   @JoinColumn(name="passnr_fk",referencedColumnName="pass_nr",unique=true)
   public Passport getPassport() {
      return passport;
   }
   public void setPassport(Passport passport) {
      this.passport = passport;
   }
}


Passport.java
Code:
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;

@Entity
public class Passport implements Serializable {
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   private Long passid;
   private Long passnr;
   private String color;
   private Customer owner;
   
   @OneToOne(mappedBy="passport")
   public Customer getOwner() {
      return owner;
   }
   public void setOwner(Customer owner) {
      this.owner = owner;
   }
   
   @Id
   @Column(name="pass_id")
   public Long getPassid() {
      return passid;
   }
   public void setPassid(Long passid) {
      this.passid = passid;
   }

   @Column(name="pass_nr")
   public Long getPassnr() {
      return passnr;
   }
   public void setPassnr(Long passnr) {
      this.passnr = passnr;
   }
   public String getColor() {
      return color;
   }
   public void setColor(String color) {
      this.color = color;
   }
}


Test.java
Code:
import hibernate.test.Customer;
import hibernate.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;


public class Test {
   public static void main(String[] args) {
      
      SessionFactory factory = HibernateUtil.getSessionFactory();
      Session session = factory.getCurrentSession();
      
      session.beginTransaction();
      Customer c1 = new Customer();
      session.load(c1,1L);
      session.getTransaction().commit();
      
      HibernateUtil.getSessionFactory().close();
      
      System.out.println(c1.getName());
      System.out.println(c1.getPassport().getColor());
   }
}


Then I get the error message:
Code:
Hibernate: select customer0_.id as id0_1_, customer0_.name as name0_1_, customer0_.passnr_fk as passnr3_0_1_, passport1_.pass_id as pass1_1_0_, passport1_.color as color1_0_, passport1_.pass_nr as pass3_1_0_ from Customer customer0_ left outer join Passport passport1_ on customer0_.passnr_fk=passport1_.pass_nr where customer0_.id=?
jan 08, 2013 10:34:14 AM org.hibernate.property.BasicPropertyAccessor$BasicGetter get
ERROR: HHH000122: IllegalArgumentException in class: hibernate.test.Passport, getter method of property: passnr
jan 08, 2013 10:34:14 AM org.hibernate.event.internal.DefaultLoadEventListener onLoad
INFO: HHH000327: Error performing load command : org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of hibernate.test.Passport.passnr
Exception in thread "main" org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of hibernate.test.Passport.passnr
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:187)
   at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:76)
   at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:82)
   at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:107)
   at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:434)
   at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:258)
   at org.hibernate.engine.spi.EntityUniqueKey.generateHashCode(EntityUniqueKey.java:85)
   at org.hibernate.engine.spi.EntityUniqueKey.<init>(EntityUniqueKey.java:66)
   at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:690)
   at org.hibernate.type.EntityType.resolve(EntityType.java:474)
   at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:168)
   at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:134)
   at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1103)
   at org.hibernate.loader.Loader.processResultSet(Loader.java:960)
   at org.hibernate.loader.Loader.doQuery(Loader.java:910)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:311)
   at org.hibernate.loader.Loader.loadEntity(Loader.java:2111)
   at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82)
   at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72)
   at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3887)
   at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:458)
   at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:427)
   at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:204)
   at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:260)
   at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:148)
   at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1078)
   at org.hibernate.internal.SessionImpl.load(SessionImpl.java:962)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
   at $Proxy9.load(Unknown Source)
   at Test.main(Test.java:17)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:164)
   ... 34 more

Pay attention that the generated hibernate query is correct. The join is being done with the right column

I've followed exactly what the hibernate user guide says...

Thank you in advance for your feedback,
T.


Top
 Profile  
 
 Post subject: Re: Join with non Primary-key column, hibernate bug?
PostPosted: Sat Jan 19, 2013 2:33 pm 
Newbie

Joined: Tue Jan 08, 2013 5:52 am
Posts: 2
I have found the problem myself...
remove (mappedBy="passport") from Passport class....
It will make Join more efficient in case you join with primary key
but if you join with non PK, then adding it will give the mentioned error...

I hope it can help someone...


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.