Hibernate EntityManager不分配自动生成的主键值

时间:2012-02-03 10:07:53

标签: java hibernate jpa derby

要求:

  • 使用javax.persistence.EntityManager的JPA Hibernate实现(NOT org.hibernate.Session)
  • 使用注释(没有特定于hibernate的XML映射文件)
  • 使用Embeded Derby作为数据库(不建议使用其他数据库)
  • 需要自动生成主键

问题:

我无法让Hibernate持久性提供程序自动生成主键。

的persistence.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
      <persistence-unit name="Contact" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.mavenproject1.Contact</class>
        <properties>
          <property name="hibernate.connection.username" value="app"/>
          <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver"/>
          <property name="hibernate.connection.password" value="app"/>
          <property name="hibernate.connection.url" value="jdbc:derby:contact;create=true"/>
          <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
          <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
      </persistence-unit>
    </persistence>

这是Java Enity类:

    package com.mavenproject1;

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

    @Entity
    public class Contact {

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        String firstName;
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getFirstName() {
            return firstName;
        }
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    }

以下是运行它的代码:

    package com.mavenproject1;

    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;

    public class App {

        public static void main(String[] args) {

            Contact c = new Contact();
            c.setFirstName("John");

            EntityManagerFactory emf =   Persistence.createEntityManagerFactory("Contact");
            EntityManager em = emf.createEntityManager();

            em.getTransaction().begin();
            em.persist(c);
            em.getTransaction().commit();
        }
    }

我得到的错误是:

    Feb 3, 2012 6:01:54 PM org.hibernate.annotations.common.Version <clinit>
    INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
    Feb 3, 2012 6:01:54 PM org.hibernate.Version logVersion
    INFO: HHH000412: Hibernate Core {4.0.1.Final}
    Feb 3, 2012 6:01:54 PM org.hibernate.cfg.Environment <clinit>
    INFO: HHH000206: hibernate.properties not found
    Feb 3, 2012 6:01:54 PM org.hibernate.cfg.Environment buildBytecodeProvider
    INFO: HHH000021: Bytecode provider name : javassist
    Feb 3, 2012 6:01:54 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
    INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
    Feb 3, 2012 6:01:54 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
    INFO: HHH000115: Hibernate connection pool size: 20
    Feb 3, 2012 6:01:54 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
    INFO: HHH000006: Autocommit mode: true
    Feb 3, 2012 6:01:54 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
    INFO: HHH000401: using driver [org.apache.derby.jdbc.EmbeddedDriver] at URL [jdbc:derby:contact;create=true]
    Feb 3, 2012 6:01:54 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
    INFO: HHH000046: Connection properties: {user=app, password=****, autocommit=true, release_mode=auto}
    Feb 3, 2012 6:01:55 PM org.hibernate.dialect.Dialect <init>
    INFO: HHH000400: Using dialect: org.hibernate.dialect.DerbyTenSevenDialect
    Feb 3, 2012 6:01:55 PM org.hibernate.dialect.DerbyDialect <init>
    WARN: HHH000430: The DerbyDialect dialect has been deprecated; use one of the version-specific dialects instead
    Feb 3, 2012 6:01:55 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
    INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
    Feb 3, 2012 6:01:55 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
    INFO: HHH000397: Using ASTQueryTranslatorFactory
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
    INFO: HHH000228: Running hbm2ddl schema update
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
    INFO: HHH000102: Fetching database metadata
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
    INFO: HHH000396: Updating schema
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.TableMetadata <init>
    INFO: HHH000261: Table found: .APP.CONTACT
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.TableMetadata <init>
    INFO: HHH000037: Columns: [id, birthday, middlename, lastname, firstname]
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.TableMetadata <init>
    INFO: HHH000108: Foreign keys: []
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.TableMetadata <init>
    INFO: HHH000126: Indexes: [sql120129125646630]
    Feb 3, 2012 6:01:55 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
    INFO: HHH000232: Schema update complete
    Feb 3, 2012 6:01:55 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    WARN: SQL Error: 20000, SQLState: 23502
    Feb 3, 2012 6:01:55 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    ERROR: Column 'ID'  cannot accept a NULL value.
    Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Column 'ID'  cannot accept a NULL value.
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:859)
        at com.mavenproject1.App.main(App.java:18)
    Caused by: org.hibernate.exception.ConstraintViolationException: Column 'ID'  cannot accept a NULL value.
        at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
        at $Proxy8.executeUpdate(Unknown Source)
        at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:58)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2757)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3268)
        at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:78)
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:304)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:128)
        at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
        at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:725)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:701)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:705)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:853)
        ... 1 more
    Caused by: java.sql.SQLIntegrityConstraintViolationException: Column 'ID'  cannot accept a NULL value.
        at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
        at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
        at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
        at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
        at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(Unknown Source)
        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.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
        ... 19 more
    Caused by: java.sql.SQLException: Column 'ID'  cannot accept a NULL value.
        at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
        at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
        ... 33 more

2 个答案:

答案 0 :(得分:3)

如果你想使用序列,你可以这样做:

@Id
@SequenceGenerator(name="id_generator", sequenceName="SEQUENCE_NAME", allocationSize=1)
@GeneratedValue(generator="id_generator", strategy=GenerationType.SEQUENCE)
private Long id;

答案 1 :(得分:1)

试试吧。 @GeneratedValue(strategy = GenerationType.IDENTITY)代替GenerationType.Auto