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.  [ 5 posts ] 
Author Message
 Post subject: mapping problem with polymorphism
PostPosted: Mon Aug 28, 2006 7:08 am 
Beginner
Beginner

Joined: Thu Aug 24, 2006 6:01 am
Posts: 49
Location: sophia-antipolis, France
Hi,

I have one class (CI) which has 2 many-to-many associations. The associations are with 2 subclasses (Factor, Status) of an abstract class (Definition). The Definition hierarchy is mapped TABLE_PER_CLASS.

On the CI-side, it seemed pretty easy, I just declare the 2 collections:

Code:
@Entity
@Table(name="CIS")
public class CI extends Id {
    private Collection<Status> statuses;
    private Collection<Factor> factors;

    @ManyToMany   
    @JoinTable(name="CI_STATUS",
        joinColumns = { @JoinColumn( name="CI_ID", referencedColumnName = "Id", nullable=false) },
        inverseJoinColumns = {@JoinColumn( name="STATUS_ID", referencedColumnName = "Id", nullable=false)})
     public Collection<Status> getStatuses() {
        return statuses;
    }

    @ManyToMany   
    @JoinTable(name="CI_FACTOR",
        joinColumns = { @JoinColumn( name="CI_ID", referencedColumnName = "Id", nullable=false) },
        inverseJoinColumns = {@JoinColumn( name="FACTOR_ID", referencedColumnName = "Id", nullable=false)})
    public Collection<Factor> getFactors() {
        return factors;
    }
}


But then I have problems on the other side. I can't put the collection of CIs
in the parent class because I have to specify the other end of the
relationship, but this depends on the subclass. So I thought I would try
putting a collection of CIs in each subclass:

Code:
@Entity
public class Factor extends Definition {
    private Collection<CI> cis;
    @ManyToMany( mappedBy="factors" )
    public Collection<CI> getCis() {
        return cis;
    }
}


Code:
@Entity
public class Status extends Definition {
    private Collection<CI> cis;
    @ManyToMany( mappedBy="statuses" )
    public Collection<CI> getCis() {
        return cis;
    }
}


Code:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Definition extends BaseObject {
   
    public abstract Collection<CI> getCis();
}


But I get the exception message listed below. I then tried moving the
collection of cis to the parent class:

Code:
@Entity
public class Factor extends Definition {

    @ManyToMany( mappedBy="factors" )
    public Collection<CI> getCis() {
        return cis;
    }
}

Code:
@Entity
public class Status extends Definition {

    @ManyToMany( mappedBy="statuses" )
    public Collection<CI> getCis() {
        return cis;
    }
}

Code:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Definition extends BaseObject {
    protected Collection<CI> cis;
    public abstract Collection<CI> getCis();
}


But I still get the same error. Does anyone know if what I'm trying to do is legal? It seems like it should be possible.

Here is my hibernate context:

Code:
   <bean id="transactionManager"
      class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="dataSource">
         <ref bean="dataSource" />
      </property>
      <property name="sessionFactory">
         <ref local="sessionFactory" />
      </property>
   </bean>
   
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="dataSource">
         <ref bean="dataSource" />
      </property>
      <property name="hibernateProperties">
         <props>
            <prop key="hibernate.dialect">
               org.hibernate.dialect.OracleDialect
            </prop>
         </props>
      </property>

     <property name="annotatedClasses">
        <list>
         <value>com.hp.ov.shm.ce.bo.BaseObject</value>   
         <value>com.hp.ov.shm.ce.bo.Definition</value>
         <value>com.hp.ov.shm.ce.bo.Factor</value>
         <value>com.hp.ov.shm.ce.bo.Status</value>
         <value>com.hp.ov.shm.ce.bo.CI</value>

         </list>
     </property>
 


Exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [hibernateObjects.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [hibernateObjects.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Collection, for columns: [org.hibernate.mapping.Column(cis)]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [hibernateObjects.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Collection, for columns: [org.hibernate.mapping.Column(cis)]
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Collection, for columns: [org.hibernate.mapping.Column(cis)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:266)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:253)
at org.hibernate.mapping.Property.isValid(Property.java:185)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:395)
at org.hibernate.mapping.RootClass.validate(RootClass.java:192)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1021)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1206)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:871)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:797)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:901)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:870)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:393)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:257)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:226)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:115)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:798)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:589)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:389)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:257)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:254)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:332)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:92)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:77)
at org.springframework.test.AbstractSpringContextTests.loadContextLocations(AbstractSpringContextTests.java:130)
at org.springframework.test.AbstractDependencyInjectionSpringContextTests.loadContextLocations(AbstractDependencyInjectionSpringContextTests.java:224)
at org.springframework.test.AbstractSpringContextTests.getContext(AbstractSpringContextTests.java:110)
at org.springframework.test.AbstractDependencyInjectionSpringContextTests.setUp(AbstractDependencyInjectionSpringContextTests.java:192)
at junit.framework.TestCase.runBare(TestCase.java:128)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:228)
at junit.framework.TestSuite.run(TestSuite.java:223)
at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:35)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 28, 2006 7:26 am 
Senior
Senior

Joined: Tue Mar 09, 2004 2:38 pm
Posts: 141
Location: Lowell, MA USA
I'll assume that your BaseObject defines the objects identifer. Second, you're using InheritanceType.TABLE_PER_CLASS, which is a union-subclass and will perform a union of the tables involved. Since this subclass type is usually reserved for the rarest of cases, I'd double check that this is indeed the strategy you want to be using. My hunch is that you are looking to use InheritanceType.JOINED or prehaps even InheritanceType.SINGLE_TABLE. If InheritanceType.TABLE_PER_CLASS is correct, you most likely will need to defined the @Table that the sub class is bound to. Otherwise, Hibernate will try yo guess the name of the table based on the class name.

Ryan-

_________________
Ryan J. McDonough
http://damnhandy.com

Please remember to rate!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 28, 2006 7:59 am 
Beginner
Beginner

Joined: Thu Aug 24, 2006 6:01 am
Posts: 49
Location: sophia-antipolis, France
I've pretty much figured out what is causing my problem: I have the getCis() method in the base class. Apparently, Hibernate interprets any method with the format get<whatever> as being a persistent attribute. Since my method is abstract, it can't figure it out.

So, renamed the abstract method in the base class, and then in the child classes, I just call the attribute accessor for cis.

Anyone know how to make Hibernate ignore certain get methods?

ps: sorry, ryan, but your reply didn't help me much. The table_per_class is what I wanted, and yes, the BaseObject is a mapped superclass which has an id. But thanks for replying anyway!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 31, 2006 4:31 pm 
Senior
Senior

Joined: Tue Mar 09, 2004 2:38 pm
Posts: 141
Location: Lowell, MA USA
You can mark the getters you want Hibernate to ignore with an @Transient annotation.

Ryan-

_________________
Ryan J. McDonough
http://damnhandy.com

Please remember to rate!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 22, 2006 11:47 am 
Beginner
Beginner

Joined: Thu Aug 24, 2006 6:01 am
Posts: 49
Location: sophia-antipolis, France
Ryan,

That was the solution to my problem, but I figured it on my own. I still gave you "yes" though. I was afraid that the @Transient would make Hibernate ignore my property entirely, but it didn't happen. I was able to override the methods in my child classes and annotate them and all is well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.