Announcement Announcement Module
Collapse
No announcement yet.
JPA @Column Annotation Being Ignored Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JPA @Column Annotation Being Ignored

    I have a Spring MVC + Data JPA webapp with Java configuration running in Tomcat 7 on Amazon 64bit Linux.
    When attempting to query the database I get the following exception:
    Code:
    com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'account0_.account_versionid' in 'field list'
    The database table definition is:
    Code:
    CREATE TABLE IF NOT EXISTS `accounts` (
      `id` INT NOT NULL AUTO_INCREMENT,
      `AccountVersionID` INT,
    ...
      PRIMARY KEY (`id`),
      INDEX `AccountVersionID` (`AccountVersionID`),
    ...
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    The model class has the following annotations:
    Code:
    @Entity
    @Table(name = "accounts")
    public class Account {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        @Column(name = "AccountVersionID")
        private int accountVersionId;
    So why is Spring Data looking for a field called "account_versionid" when I have the @Column annotation with name="AccountVersionID"?

    The libs brought in by my maven dependencies are as follows:
    Code:
    436K antlr-2.7.7.jar
    8.0K aopalliance-1.0.jar
     44K asm-3.3.jar
    116K aspectjrt-1.7.2.jar
    9.6M aws-java-sdk-1.4.3.jar
    116K bonecp-0.7.1.RELEASE.jar
    276K cglib-2.2.jar
     48K commons-codec-1.3.jar
     68K commons-fileupload-1.3.jar
    184K commons-io-2.4.jar
    280K commons-lang-2.6.jar
     60K commons-logging-1.1.1.jar
    308K dom4j-1.6.1.jar
    1.1M guava-r08.jar
     80K hibernate-commons-annotations-4.0.2.Final.jar
    4.5M hibernate-core-4.2.2.Final.jar
    476K hibernate-entitymanager-4.2.2.Final.jar
    104K hibernate-jpa-2.0-api-1.0.1.Final.jar
    468K hibernate-validator-4.3.1.Final.jar
    344K httpclient-4.1.jar
    180K httpcore-4.1.jar
    224K jackson-core-asl-1.8.9.jar
    656K jackson-mapper-asl-1.8.9.jar
    636K javassist-3.15.0-GA.jar
     60K jboss-logging-3.1.0.GA.jar
     28K jboss-transaction-api_1.1_spec-1.0.1.Final.jar
     20K jcl-over-slf4j-1.7.1.jar
    408K jstl-1.2.jar
    472K log4j-1.2.16.jar
    832K mysql-connector-java-5.1.25.jar
     28K slf4j-api-1.7.5.jar
     12K slf4j-log4j12-1.7.5.jar
    328K spring-aop-3.1.4.RELEASE.jar
     52K spring-asm-3.1.4.RELEASE.jar
    584K spring-beans-3.1.4.RELEASE.jar
    820K spring-context-3.1.4.RELEASE.jar
    444K spring-core-3.1.4.RELEASE.jar
    316K spring-data-commons-1.5.1.RELEASE.jar
    144K spring-data-jpa-1.3.2.RELEASE.jar
    192K spring-expression-3.2.3.RELEASE.jar
    400K spring-jdbc-3.1.4.RELEASE.jar
    372K spring-orm-3.1.4.RELEASE.jar
    240K spring-tx-3.1.4.RELEASE.jar
    612K spring-web-3.2.3.RELEASE.jar
    624K spring-webmvc-3.2.3.RELEASE.jar
     48K validation-api-1.0.0.GA.jar
    My maven dependencies in my pom.xml are:
    Code:
      <properties>
        <asm.version>3.3</asm.version>
        <aws-java-sdk.version>1.4.3</aws-java-sdk.version>
        <bonecp.version>0.7.1.RELEASE</bonecp.version>
        <cglib.version>2.2</cglib.version>
        <commons-fileupload.version>1.3</commons-fileupload.version>
        <commons-lang.version>2.6</commons-lang.version>
        <commons-io.version>2.4</commons-io.version>
        <hibernate.version>4.2.2.Final</hibernate.version>
        <hibernate-validator.version>4.3.1.Final</hibernate-validator.version>
        <javax.servlet-api.version>3.0.1</javax.servlet-api.version>
        <jdk.version>1.6</jdk.version>
        <jstl.version>1.2</jstl.version>
        <junit.version>4.11</junit.version>
        <log4j.version>1.2.16</log4j.version>
        <mysql-connector-java.version>5.1.25</mysql-connector-java.version>
        <slf4j.version>1.7.5</slf4j.version>
        <spring.version>3.2.3.RELEASE</spring.version>
        <spring-data-jpa.version>1.3.2.RELEASE</spring-data-jpa.version>
        <validation-api.version>1.0.0.GA</validation-api.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
      <dependencies>
        <dependency>
          <groupId>asm</groupId>
          <artifactId>asm</artifactId>
          <version>${asm.version}</version>
        </dependency>
        <dependency>
          <groupId>com.amazonaws</groupId>
          <artifactId>aws-java-sdk</artifactId>
          <version>${aws-java-sdk.version}</version>
        </dependency>
        <dependency>
          <groupId>com.jolbox</groupId>
          <artifactId>bonecp</artifactId>
          <version>${bonecp.version}</version>
        </dependency>
        <dependency>
          <groupId>cglib</groupId>
          <artifactId>cglib</artifactId>
          <version>${cglib.version}</version>
        </dependency>
        <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>${commons-fileupload.version}</version>
        </dependency>
        <dependency>
          <groupId>commons-lang</groupId>
          <artifactId>commons-lang</artifactId>
          <version>${commons-lang.version}</version>
        </dependency>
        <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>${commons-io.version}</version>
        </dependency>
        <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-core</artifactId>
          <version>${hibernate.version}</version>
        </dependency>
        <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-entitymanager</artifactId>
          <version>${hibernate.version}</version>
        </dependency>
        <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-validator</artifactId>
          <version>${hibernate-validator.version}</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>${javax.servlet-api.version}</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>jstl</groupId>
          <artifactId>jstl</artifactId>
          <version>${jstl.version}</version>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>${junit.version}</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>${log4j.version}</version>
        </dependency>
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>${mysql-connector-java.version}</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>${slf4j.version}</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>${slf4j.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework.data</groupId>
          <artifactId>spring-data-jpa</artifactId>
          <version>${spring-data-jpa.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>javax.validation</groupId>
          <artifactId>validation-api</artifactId>
          <version>${validation-api.version}</version>
        </dependency>
      </dependencies>
    My web.xml is simply:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>MyApp</display-name>
    </web-app>
    Here's my Initializer class:
    Code:
    public class Initializer implements WebApplicationInitializer {
        private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
        public void onStartup(ServletContext servletContext)
                throws ServletException {
            AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
            ctx.register(AppContextConfig.class);
            servletContext.addListener(new ContextLoaderListener(ctx));
            ctx.setServletContext(servletContext);
            Dynamic servlet = servletContext.addServlet(DISPATCHER_SERVLET_NAME,
                    new DispatcherServlet(ctx));
            servlet.addMapping("/");
            servlet.setLoadOnStartup(1);
        }
    }
    My application context config class looks like this:
    Code:
    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = {"xxx.controller", "xxx.service"})
    @PropertySource(value = "classpath:application.properties")
    @EnableTransactionManagement
    @EnableJpaRepositories("xxx.repository")
    public class AppContextConfig extends WebMvcConfigurerAdapter {
    ...
        @Resource
        Environment env;
    ....
        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory()
                throws ClassNotFoundException {
            LocalContainerEntityManagerFactoryBean entityManagerFactoryBean =
                    new LocalContainerEntityManagerFactoryBean();
            entityManagerFactoryBean.setDataSource(dataSource());
            String pkg = env.getRequiredProperty("entitymanager.packages.to.scan");
            entityManagerFactoryBean.setPackagesToScan(pkg);
            entityManagerFactoryBean.setPersistenceProviderClass(
                    HibernatePersistence.class);
            Properties jpaProterties = new Properties();
            jpaProterties.put(PROPERTY_NAME_HIBERNATE_DIALECT,
                    env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
            jpaProterties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL,
                    env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
            jpaProterties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY,
                    env.getRequiredProperty(
                    PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
            jpaProterties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,
                    env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
            entityManagerFactoryBean.setJpaProperties(jpaProterties);
            return entityManagerFactoryBean;
        }
    }
    Any ideas why the annotations don't seem to get parsed or are being ignored?
    Thanks!
    Shawn
    Last edited by shawnim; Jul 3rd, 2013, 05:07 AM. Reason: add code markup and maven dependencies

  • #2
    Please use [ code][/code ] tags when po sting code/xml/stacktraces... That way they remain readable, currently it isn't readable.

    For starters fix your spring versions, you are mixing 2 different versions 3.1.4 and 3.2.3, next make sure you use the correct @Column annotation.

    Comment


    • #3
      Not mixing versions

      Hi Marten,
      Thanks for the reply.
      I fixed the code markup.
      I also added the maven dependencies I am using.
      I am only specifying 3.2.3 for spring version not 3.1.4.
      i believe 3.1.4 is the latest available for those particular jars.
      What did you mean when you said to fix my Column annotation?
      What is wrong with it?
      Any other ideas appreciated.
      Thanks.
      Shawn

      Comment


      • #4
        I'm pretty sure that account0_.account_versionid is what Hibernate, not Spring Data JPA, is generating.

        I'm going to take a wild guess and say that you have an orm.xml file which defines the column name as account_versionid.

        Otherwise, I don't know why Hibernate would think it should insert an underscore into the name. But I have to ask, why you need to even define the column name in the @Column annotation since it's the same as the member variable/field.

        I just took your column and field definition, stuck it into the Account entity (a part of sample code I used to answer another question in this forum), altered my Account table in MySQL using your DDL, and it works just fine. Here's the Hibernate-generated SQL:

        Code:
        select account0_.id as id0_, account0_.AccountVersionID as AccountV2_0_, account0_.expiryDate as expiryDate0_ from account account0_
        So my bet is on the presence of an orm.xml file in which account_versionid is the declared name.

        Comment


        • #5
          Well actually I guess it is neither... Looking at the configuration again I noticed that he sets the hibernate naming strategy... If you set that to the something else it could be that that is ignoring the @Column and generating the names (Only the Ejb3 strategy knows what to do with it.

          Comment


          • #6
            Thanks for the reply! I don't have any orm.xml file in my app. I am wondering if it is because I am using all java configuration instead of xml. Does your working sample code use xml configuration? Can you share your code? I have looked at other example code on the spring site, Petri Kainulainen's, and Fruzenshtein's but they all seem to use mixed java and xml config or xml only. I am using java configuration in order to be able to set the datasource properties from the system properties set by Amazon Elastic Beanstalk for Amazon RDS. Since these can change I did not want to hardcode them into an xml config file.
            Anyway thanks for taking a look.
            Anyone who can point me at working sample code showing Spring MVC + Data JPA using java configuration and working @Table and @Column annotations would be greatly appreciated.
            Thanks.
            Shawn

            Comment


            • #7
              That was it!
              I commented out the setting of the naming strategy and everything worked!
              Thank you, thank you, thank you!!!
              Shawn

              Comment


              • #8
                [edit: Ah, I see you commented out the naming strategy setting and things work. Great! Kudos to Marten.]

                I am wondering if it is because I am using all java configuration ...
                These days, I am prone to using Java configuration, so yes, it works with Java configuration. The only thing which I usually configure using XML is the datasource: it just seems more flexible or manageable that way for me.


                I think Marten's eagle eye may have found the problem. Why do you change/set the naming strategy? (I cannot recall having ever changed it ... but I have a short memory.)

                I just googled "Kainulainen hibernate.ejb.naming.strategy" and found this where he uses Hibernate's ImprovedNamingStrategy. The "improved" naming strategy inserts "_" between "words" in table names and columns.

                From the JavaDoc for org.hibernate.cfg.ImprovedNamingStrategy:
                Code:
                /**
                 * An improved naming strategy that prefers embedded
                 * underscores to mixed case names
                 * @see DefaultNamingStrategy the default strategy
                 * @author Gavin King
                 */
                public class ImprovedNamingStrategy implements NamingStrategy, Serializable { ....
                In your case, since your table and column naming strategy seems to be one without underscores in table and column names, you probably don't want to configure this and just use the default.

                Comment


                • #9
                  Thank you both for taking the time to look at this!
                  I really appreciate it!
                  Shawn

                  Comment

                  Working...
                  X