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: Parent one-to-many / many-to-one Child
PostPosted: Tue Apr 20, 2010 9:31 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
Note: I think I solved it. I just need confirmation. Please see second post.

I have a parent/child situation I can't get working.
I have Country (parent) which contains cities (children).

These are my mappings:
Code:
   <class name="data.Country" table="countries">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>

      <set name="cities" table="cities" inverse="true" cascade="all-delete-orphan">
         <key column="country" />
         <one-to-many class="data.City" />
      </set>
   </class>
Code:
   <class name="data.City" table="cities">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>

      <many-to-one name="country" class="data.Country" column="country" />
   </class>
And these are the java classes:
Note they extend Data.
Code:
public class Country extends Data
{
   private Set<City> cities = new HashSet<City>(0);
   
   /* Constructors */
   public Country(String id)
   {
      setId(IdCounter.getInstance().getCountryId());
   }
   
   /* Getters */
   public Set<City> getCities()
   {
      return cities;
   }
   
   /* Setters */
   public void setCities(Set<City> cities)
   {
      this.cities = cities;
   }
   
   /* Override */
   public boolean equals(Object o)
   {
      if (o instanceof Country)
         return ((Country) o).getId().equals(id);
      else
         return false;
   }
}
Code:
public class City extends Data
{
   private Country country;
   
   /* Constructors */
   public City(Country country)
   {
      setId(IdCounter.getInstance().getCityId());
      setCountry(country);
   }
   
   /* Getters */
   public Country getCountry()
   {
      return country;
   }
   
   /* Setters */
   public void setCountry(Country country)
   {
      this.country = country;
   }
   
   /* Override */
   public boolean equals(Object o)
   {
      if (o instanceof City)
         return ((City) o).getId().equals(id);
      else
         return false;
   }
}
Code:
public abstract class Data
{
   protected String id;
   
   /* Getters */
   public String getId()
   {
      return id;
   }
   
   /* Setters */
   protected void setId(String id)
   {
      this.id = id;
   }
   
   /* Override */
   public abstract boolean equals(Object o);
   
   public int hashCode()
   {
      return new HashCodeBuilder().append(id).toHashCode();
   }
   
   public String toString()
   {
      return id;
   }
}
I use this code to test:
Code:
      try
      {
         Criteria crit = session.createCriteria(City.class).add(Restrictions.eq("country", "Auke-yyyy-DDD-kk-mm-ss-SSS-0001"));
         Logger.get().error("Testing: 1");
         List<City> list = crit.list();
         Logger.get().error("Testing: 2");
         Country country = list.get(0).getCountry();
         System.out.println(country.getId());
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
And this is the error I get:
Quote:
ERROR - (HibernateMain.java:21) - Testing: 1
ERROR - (BasicPropertyAccessor.java:191) - IllegalArgumentException in class: data.Data, getter method of property: id
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of data.Data.id

at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:195)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:206)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3619)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3335)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:204)
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:241)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:430)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:110)
at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1728)
at org.hibernate.loader.Loader.bindParameterValues(Loader.java:1699)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1589)
at org.hibernate.loader.Loader.doQuery(Loader.java:696)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2228)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
at org.hibernate.loader.Loader.list(Loader.java:2120)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:118)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1596)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
at main.HibernateMain.main(HibernateMain.java:22)
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(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:169)
... 19 more
As you can see the error starts at: List<City> list = crit.list();

Edit: if I don't use the abstract Data class and copy the code to country and city, the same error occurs, so the inheritance isn't a problem.


Last edited by aukemid on Tue Apr 20, 2010 10:32 am, edited 5 times in total.

Top
 Profile  
 
 Post subject: Re: One-to-many / Many-to-one
PostPosted: Tue Apr 20, 2010 10:14 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
...

Edit: I think I found my problem, I've tested and it seems allright.
Can someone confirm what I think:
When using Criteria do you have to compare a foreign key to the object or can you also compare to the id of the object.

Example: Country.getCountryById() returns the Country object
Should both lines work?
Code:
Criteria crit = session.createCriteria(City.class).add(Restrictions.eq("country", "Auke-yyyy-DDD-kk-mm-ss-SSS-0001"));
Criteria crit = session.createCriteria(City.class).add(Restrictions.eq("country", Country.getCountryById(session, "Auke-yyyy-DDD-kk-mm-ss-SSS-0001")));


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.