1

我有三个实体A,B,C。

A有很多B和C,B有很多C。我想有双向关系。

我在 Hibernate 中映射了所有这些:

@Entity
    @Table(name="TABLE_A")
    class A{

        @Id
        @GeneratedValue
        private Integer a_id;

        @ManyToOne
        C c; 

        @OneToMany
        List<B> bs;
    }

    @Entity
    @Table(name="TABLE_B")
    class B{

        @Id
        @GeneratedValue
        private Integer b_id;

        @ManyToOne
        A a; // inverse

        @ManyToOne
        C c;
    }

    @Entity
    @Table(name="TABLE_C")
    class C{

        @Id
        @GeneratedValue
        private Integer c_id;

        @ManyToMany(mappedBy="c")
        List<B> b; // inverse

        @ManyToMany(mappedBy="c")
        List<A> a; //inverse

    }

我使用 SchemaUpdate 来获取在 MySQL 中生成的表。问题如下:

2012-08-24 14:57:15,437 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_A add index FKCE3C1BF0B8CF4F47 (a_id), add constraint FKCE3C1BF0B8CF4F47 foreign key (a_id) references TABLE_A (a_id)

将约束添加到 A 到自身 - 这可能是由于 C->A 关系。映射有什么问题?

我创建了一个简单的测试文件:

    @Test
        public void tests() throws Exception {
            Logger l = Logger.getLogger("org.hibernate.tool.hbm2ddl");
            l.

setLevel(Level.DEBUG);

        //Hibernate.enableCreationDebug();
        A a = new A();

        SessionFactory sf = configureSessionFactory();
        Session session = sf.openSession();
        Transaction tx = session.beginTransaction();
        try{

            session.save(a);
            tx.commit();
        }catch(Exception e){
            tx.rollback();
            throw e;
        }finally{
            session.close();
        }

        session = sf.openSession();
        tx = session.beginTransaction();
        try{

            session.delete(a);
            tx.commit();
        }catch(Exception e){
            tx.rollback();
            throw e;
        }finally{
            session.close();
        }

    }

private static SessionFactory configureSessionFactory() throws HibernateException {
        Configuration configuration = new Configuration();

        String DB_USER_NAME = "kiri";
        String DB_USER_PWD = "kiri";
        String JDBC_CONNECTION_STRING = "jdbc:mysql://localhost/kiri";

        configuration
                .addAnnotatedClass(HibernateCyclicTest.A.class)
                .addAnnotatedClass(HibernateCyclicTest.B.class)
                .addAnnotatedClass(HibernateCyclicTest.C.class)

                .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect")
                .setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver")
                .setProperty("hibernate.connection.url", JDBC_CONNECTION_STRING)
                .setProperty("hibernate.connection.username", DB_USER_NAME)
                .setProperty("hibernate.connection.password", DB_USER_PWD);


        // Create or update the schema to match our objects
        org.hibernate.tool.hbm2ddl.SchemaUpdate schemaUpdate = new SchemaUpdate(configuration);
        schemaUpdate.execute(false,/* update schema */true);
        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
                .buildServiceRegistry();
        SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        return sessionFactory;
    }

这是输出:

    2012-08-24 15:03:01,719 [main] INFO  org.hibernate.tool.hbm2ddl.SchemaUpdate - HHH000228: Running hbm2ddl schema update
2012-08-24 15:03:01,719 [main] INFO  org.hibernate.tool.hbm2ddl.SchemaUpdate - HHH000102: Fetching database metadata
2012-08-24 15:03:01,923 [main] INFO  org.hibernate.tool.hbm2ddl.SchemaUpdate - HHH000396: Updating schema
2012-08-24 15:03:02,025 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_A
2012-08-24 15:03:02,025 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_A_TABLE_B
2012-08-24 15:03:02,026 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_B
2012-08-24 15:03:02,026 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_C
2012-08-24 15:03:02,027 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_A
2012-08-24 15:03:02,027 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_A_TABLE_B
2012-08-24 15:03:02,028 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_B
2012-08-24 15:03:02,029 [main] INFO  java.sql.DatabaseMetaData - HHH000262: Table not found: TABLE_C
2012-08-24 15:03:02,030 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - create table TABLE_A (a_id integer not null auto_increment, c_c_id integer, primary key (a_id)) ENGINE=InnoDB
2012-08-24 15:03:02,051 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - create table TABLE_A_TABLE_B (TABLE_A_a_id integer not null, bs_b_id integer not null, unique (bs_b_id)) ENGINE=InnoDB
2012-08-24 15:03:02,062 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - create table TABLE_B (b_id integer not null auto_increment, a_a_id integer, c_c_id integer, primary key (b_id)) ENGINE=InnoDB
2012-08-24 15:03:02,070 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - create table TABLE_C (c_id integer not null auto_increment, primary key (c_id)) ENGINE=InnoDB
2012-08-24 15:03:02,078 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_A add index FKCE3C1BF0B8CF4F47 (a_id), add constraint FKCE3C1BF0B8CF4F47 foreign key (a_id) references TABLE_A (a_id)
2012-08-24 15:03:02,087 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_A add index FKCE3C1BF066FAB663 (c_c_id), add constraint FKCE3C1BF066FAB663 foreign key (c_c_id) references TABLE_C (c_id)
2012-08-24 15:03:02,097 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_A_TABLE_B add index FK64E4EEA2F8F999F6 (TABLE_A_a_id), add constraint FK64E4EEA2F8F999F6 foreign key (TABLE_A_a_id) references TABLE_A (a_id)
2012-08-24 15:03:02,107 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_A_TABLE_B add index FK64E4EEA2C26A7AD5 (bs_b_id), add constraint FK64E4EEA2C26A7AD5 foreign key (bs_b_id) references TABLE_B (b_id)
2012-08-24 15:03:02,123 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_B add index FKCE3C1BF1B8CFC3A7 (b_id), add constraint FKCE3C1BF1B8CFC3A7 foreign key (b_id) references TABLE_B (b_id)
2012-08-24 15:03:02,141 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_B add index FKCE3C1BF163901C65 (a_a_id), add constraint FKCE3C1BF163901C65 foreign key (a_a_id) references TABLE_A (a_id)
2012-08-24 15:03:02,151 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table TABLE_B add index FKCE3C1BF166FAB663 (c_c_id), add constraint FKCE3C1BF166FAB663 foreign key (c_c_id) references TABLE_C (c_id)
2012-08-24 15:03:02,161 [main] INFO  org.hibernate.tool.hbm2ddl.SchemaUpdate - HHH000232: Schema update complete
2012-08-24 15:03:02,583 [main] WARN  org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1451, SQLState: 23000
2012-08-24 15:03:02,583 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Cannot delete or update a parent row: a foreign key constraint fails (`kiri`.`table_a`, CONSTRAINT `FKCE3C1BF0B8CF4F47` FOREIGN KEY (`a_id`) REFERENCES `TABLE_A` (`a_id`))

这是堆栈:

    org.hibernate.exception.ConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`kiri`.`table_a`, CONSTRAINT `FKCE3C1BF0B8CF4F47` FOREIGN KEY (`a_id`) REFERENCES `TABLE_A` (`a_id`))
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    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 $Proxy13.executeUpdate(Unknown Source)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3134)
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3337)
    at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:100)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:280)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1214)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:403)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at com.kireego.tests.HibernateCyclicTest.tests(HibernateCyclicTest.java:59)
    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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`kiri`.`table_a`, CONSTRAINT `FKCE3C1BF0B8CF4F47` FOREIGN KEY (`a_id`) REFERENCES `TABLE_A` (`a_id`))
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1040)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4074)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4006)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2468)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2450)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2371)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2355)
    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)
    ... 39 more

感谢您的帮助。

4

1 回答 1

1

我只是删除了mappedBy创建额外表但解决了问题的属性。

于 2012-10-12T12:18:56.493 回答