views:

40

answers:

1

I am trying to work out how to do the mappings for two different projects that share some entities. Since they share only a limited subset of mappings, my first idea was to separate these mappings out into a separate jar. I'm using hibernate annotations to do the mappings (so they're in the class files, not separate XML).

Both project A and project B depend on this mappings project, which contains only a couple of hibernate mappings. Project A has no mappings of its own but project B does. Whatever I do this always seems to cause problems since if I don't configure a persistence unit for the mappings project, the mappings are never picked up on. Likewise for project B. If I do configure a persistence unit in the mappings project, project A works, but running a query in project B just gives me (Mapping happens to be the name of the class):

java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: Mapping is not mapped

I believe this is caused by project B having its own persistence unit, and obviously the two are not being merged. I don't really want them to either, I'd prefer to only configure one in project A/B and not the jar they depend on. So is there a way to tell hibernate to scan and map the annotations in a dependency jar and add them to the current persistence unit?

+1  A: 

I do not know whether you use Spring but i use Spring capabilities To get this behavior by using packagesToScan property among with mappingLocations property as follows

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mappingLocations">
        <util:list>
            <value>classpath:br/com/ar/model/repository/hql.ar.hbm.xml</value>
            <value>classpath:br/com/br/model/repository/hql.br.hbm.xml</value>
            <value>classpath:br/com/cr/model/repository/hql.cr.hbm.xml</value>
        </util:list>
    </property>
    <property name="packagesToScan">
        <util:list>
            <value>br.com.ar.model.domain</value>
            <value>br.com.br.model.domain</value>
            <value>br.com.cr.model.domain</value>
        </util:list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
            <prop key="hibernate.connection.charSet">UTF-8</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.validator.autoregister_listeners">false</prop>
        </props>
    </property>
</bean>

I hope It can be useful

UPDATE

According To JPA specification

The set of managed persistence classes that are managed by a persistence unit is defined by using one or more of the following:

  • One or more object/relational mapping XML files
  • One or more jar files that will be searched for classes
  • An explicit list of the classes
  • The annotated managed persistence classes contained in the root of the persistence unit (unless the exclude-unlisted-classes element is specified)

As follows

<persistence>
    <persistence-unit name="titan">
        <!--Explicity list of classes-->
        <class>br.com.ar.model.domain.A</class>
        <class>br.com.ar.model.domain.B</class>
        <!--Set up any jar file by using jar-file element-->
        <!--Its value is a path relative to the JAR file that contains persistence.xml-->
        <jar-file>../lib/customer.jar</jar-file>
        <!--ORM mapping file-->
        <!--It may be present anywhere on the class path-->
        <mapping-file>mapping.xml</mapping-file>
        <properties>
            Properties goes here
        </properties>
    </persistence-unit>
</persistence>
Arthur Ronald F D Garcia
Thanks that looks useful. I'm not creating the SessionFactory myself but through spring's LocalContainerEntityManagerFactoryBean (i.e. it's constructing HibernatePersistence by looking at persistence.xml). Quite possibly that is just wrong, but you don't happen to know how to achieve the same result through some configuration in the persistence file?
wds
@wds Sorry but As far As i know, LocalContainerEntityManagerFactoryBean does not provide similar behavior. See update
Arthur Ronald F D Garcia
Okay thanks. It seems either way separating mappings is not going to be a timesaver. The interfaces are fairly stable and changes on a DB level will probably require logic changes in both projects' code, so I'm going to copy the mappings over for now (only 3 classes, after all, but that's how it starts). I'm accepting your answer because it answers the question, tho not in the way I hoped. :-)
wds