views:

208

answers:

3

Hi,i am coming back because i still have problem using JodaTime. After the previous comments, i modified my pom and the @Type annotation is fixed. Here is my new pom :

<properties>
    <org.springframework.version>3.0.3.RELEASE</org.springframework.version>
    <hibernate.version>3.6.0.Beta1</hibernate.version>
</properties>
<dependencies>
     ...
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <!-- Spring Dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>3.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>20030825.184428</version>
    </dependency>
    <dependency>
        <groupId>commons-pool</groupId>
        <artifactId>commons-pool</artifactId>
        <version>20030825.183949</version>
    </dependency>
    <dependency>
        <groupId>commons-validator</groupId>
        <artifactId>commons-validator</artifactId>
        <version>1.3.1</version>
        <classifier>sources</classifier>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.5</version>
    </dependency>

    <!-- Joda Time dependencies -->
    <dependency>
        <artifactId>joda-time</artifactId>
        <groupId>joda-time</groupId>
        <version>1.6</version>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time-jsptags</artifactId>
        <version>1.0.2</version>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time-hibernate</artifactId>
        <version>1.2</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>
</dependencies>

I am actually developping a personnal project where i use Spring and Hibernate. I also use JodaTime to persist the date fields. When i am doing unit testing with Junit4, i caught this exception :

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [spring/spring-dao.xml]: Invocation of init method failed; nested exception is java.lang.IncompatibleClassChangeError: Implementing class
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
  ....  
fr.cc2i.intervention.dao.test.WebInterventionTest.oneTimedSetUp(WebInterventionTest.java:33)
    .....
    Caused by: java.lang.IncompatibleClassChangeError: Implementing class
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
    at java.lang.Class.getConstructor0(Class.java:2699)
    at java.lang.Class.getDeclaredConstructor(Class.java:1985)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
    at 
           .....

According to that website : http://www.mail-archive.com/[email protected]/msg00609.html, jodatime might cause the error.

Can someone explain me what is : java.lang.incompatibleChangeError : Implementing Class ? and how to solve that problem?

My spring configuration :

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource"> <ref local="dataSource" /></property> 
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.current_session_context_class">thread</prop>
            <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>

            <!-- Pour les requetes SQL -->
            <prop key="hibernate.query.substitutions">true 1, false 0, yes 'Y', no 'N'</prop>

            <!-- manipuler avec attention       -->
            <prop key="hibernate.hbm2ddl.auto">create</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>

        </props>
    </property>
    <property name="annotatedClasses">
        <list>
            <value>fr.cc2i.intervention.dao.beans.Client</value>
            <value>fr.cc2i.intervention.dao.beans.Intervention</value>
            <value>fr.cc2i.intervention.dao.beans.Technicien</value>
            <value>fr.cc2i.intervention.dao.beans.Contrat</value>               
        </list>
    </property>
</bean>

My entity class :

    package fr.cc2i.intervention.dao.beans;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Type;
import org.joda.time.Period;

/**
 * Classe définissant un contrat
 * My code is written in French ;)
 * @author lindows
 *
 */
@Entity
@Table(name="T_Contrat")
public class Contrat {

    private long id;

    private String reference;

    private Period heures_totales;

    private Period heures_restantes;


    public Contrat(){}

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

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


    public String getReference() {
        return reference;
    }

    public void setReference(String reference) {
        this.reference = reference;
    }

    @Column
    @Type(type="org.joda.time.contrib.hibernate.PersistantPeriod")
    public Period getHeures_totales() {
        return heures_totales;
    }

    public void setHeures_totales(Period heuresTotales) {
        heures_totales = heuresTotales;
    }

    @Column
    @Type(type="org.joda.time.contrib.hibernate.PersistantPeriod")
    public Period getHeures_restantes() {
        return heures_restantes;
    }

    public void setHeures_restantes(Period heuresRestantes) {
        heures_restantes = heuresRestantes;
    }

    public String toString(){
        return this.reference + " - \n Heures totales :" + this.heures_totales.toString() + 
         " Heures Restantes : " + this.heures_restantes.toString();
    }

}

Thanks for your help

+1  A: 

The @Type annotation is present in hibernate-annotations, version 3.5.1-Final. I don't find the snapshot you are using 3.6.0-SNAPSHOT in the jboss repository, so I couldn't test that specifically, but my guess is that the annotation is missing/has been removed from the snapshot version for some reason.

Unless there is a specific reason you need a snapshot, I would stick to released versions. If you revert to 3.5.1-Final, that will fix the problem.

mdma
Hi, thanx for your answer. I finally switch to 3.5.5-SNAPSHOT version and it works. Thanks for your answer
Dimitri
+1  A: 

As I wrote in a comment, your pom.xml is messy and this is somehow the root cause of the issue. Here comes the full explanation.

According to the announcement of the Simultaneous Hibernate 3.5.4 and 3.6.0.Beta1 Releases quoted below, the hibernate-annotations module has been merged into core in Hibernate 3.6.x (made possible since Hibernate 3.6.x is dropping JDK 1.4 support):

3.6.0.Beta1

3.6 introduces some new features as well as incorporating most of the fixes from 3.5. Changes of particular interest include

  • Dropping support for JDK 1.4
  • merging some modules into core; specifically hibernate-jmx and hibernate-annotations
  • repackaging of classes in hibernate-testing
  • HHH-2277 : fixes a long known limitation in key-many-to-one support.
  • HHH-5138, HHH-5182, HHH-5262 : collectively address a number of improvements to the "Hibernate type system". See the newly separated and expanded chapter on Types in the reference manual for details.
  • HHH-5268 : java.util.UUID support

For more details about 3.6.0.Beta1, including the full list of changes, see the release page.

And indeed, the latest versions of hibernate-annotations-3.6-SNAPSHOT.jar are actually empty jars (because of the merge) that were temporarily built until the total removal of the maven module itself. But because you're not using hibernate-core-3.6-SNAPSHOT.jar, you just don't have the @Type annotation at all.

Now, here is a summary of my recommendations/remarks:

  • Use Maven transitive dependency resolution mechanism, do not declare all dependencies but only the "top level" one i.e. hibernate-entitymanager if you want to use JPA.
  • Starting with version 3.5, Hibernate Core, Annotations, EntityManager are released together, their versions are in sync.
  • If you want to use Hibernate 3.6.x (Beta2 is there now), the @Type is in hibernate-core (that's not really important if you use transitive dependencies).
  • I don't recommend to rely on SNAPSHOT unless you know exactly what you're doing.

So your pom.xml should declare something like this for Hibernate:

<project>
  ...
  <properties>
    <!--hibernate.version>3.4.O.GA</hibernate.version-->    <!-- for JPA 1.0 -->
    <hibernate.version>3.5.4-Final</hibernate.version>      <!-- for JPA 2.0 -->
    <!--hibernate.version>3.6.0.Beta2</hibernate.version--> <!-- experimental -->
  <properties>
  ...
  <dependencies>
    <!-- Hibernate dependencies -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    ...    
  </dependencies>
  ...
</project>

And that's all you need.

Pascal Thivent
Thanks for your advice Pascal, i made the correct changes and it works very well.
Dimitri
A: 

Hi,

The Type API is changing in Hibernate 3.6.0. I would be surprised if the Joda Time Contrib classes work at all with Hibernate 3.6 although they should work with Hibernate 3.5. Can I suggest you take a look at my project which has implementations of Usertypes for Joda Time and JSR310: http://usertype.sourceforge.net/

Thanks and regards,

Chris

Chris Pheby