zoukankan      html  css  js  c++  java
  • hibernate 多对多

    Category                                 Item

    类别                                         商品

    单向多对多。

    package com.hibernate.n2n;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class Category {
        private Integer cid;
        private String cname;
        private Set<Item> items=new HashSet<Item>();
        public Integer getCid() {
            return cid;
        }
        public void setCid(Integer cid) {
            this.cid = cid;
        }
        public String getCname() {
            return cname;
        }
        public void setCname(String cname) {
            this.cname = cname;
        }
        public Set<Item> getItems() {
            return items;
        }
        public void setItems(Set<Item> items) {
            this.items = items;
        }
        
    }
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping package="com.hibernate.n2n">
    
        <class name="Category" table="categories">
            
            <id name="cid" type="java.lang.Integer">
                <column name="c_id" />
                <!-- 指定主键的生成方式, native: 使用数据库本地方式 -->
                <generator class="native" />
            </id>
        
            <property name="cname" 
                type="java.lang.String" column="c_name" >
            </property>
            <!-- name  对应items的属性名。  table  是一个中间表-->
            <set name="items" table="Category_Items">
                <key column="c_id"></key>    设置category在中间表的外键
                <many-to-many class="Item" column="i_id" ></many-to-many>   设置item在中间表的外键。
            </set>
            
        </class>
        
    </hibernate-mapping>
    package com.hibernate.n2n;
    
    public class Item {
        private Integer iid;
        private String iname;
        public Integer getIid() {
            return iid;
        }
        public void setIid(Integer iid) {
            this.iid = iid;
        }
        public String getIname() {
            return iname;
        }
        public void setIname(String iname) {
            this.iname = iname;
        }
        
    }
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping package="com.hibernate.n2n">
    
        <class name="Item" table="item" >
            
            <id name="iid" type="java.lang.Integer">
                <column name="i_id" />
                <!-- 指定主键的生成方式, native: 使用数据库本地方式 -->
                <generator class="native" />
            </id>
        
            <property name="iname"
                type="java.lang.String" column="i_name" >
            </property>
            
         </class>
        
    </hibernate-mapping>

    测试添加:

    @org.junit.Test
        public void testSave(){
            Category category1=new Category();
            category1.setCname("CA1");
            Category category2=new Category();
            category2.setCname("CA1");
            
            Item item1=new Item();
            item1.setIname("IA1");
            Item item2=new Item();
            item2.setIname("IA2");
            //维护关系.
            category1.getItems().add(item1);
            category1.getItems().add(item2);
            
            category2.getItems().add(item1);
            category2.getItems().add(item2);
            
            session.save(category1);
            session.save(category2);
            session.save(item1);
            session.save(item2);
            
        }

    也是支持懒加载的。

    查询item的时候。是查询的中间表。

    双向N---N

    只是在对象中加上set集合。

    配置文件加上:set

    1 <set name="categorys" table="Category_Items">   在item对象中的category属性。
    2             <key column="i_id"></key>   item在中间表中的外键
    3             <many-to-many class="Category" column="c_id" ></many-to-many>   category在中间表中的外键。
    4         </set>

    执行保存的时候会出现错误。 这是因为双方都维护了关系。导致主键发生冲突。

    解决方案:在其中一个set 加上 inverse="true"

    org.hibernate.exception.ConstraintViolationException: could not execute statement
        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.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)
        at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:58)
        at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1256)
        at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:292)
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339)
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
        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.hibernate.n2n.Test.destroy(Test.java:34)
        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.RunAfters.evaluate(RunAfters.java:37)
        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: Duplicate entry '8-5' for key 'PRIMARY'
        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:406)
        at com.mysql.jdbc.Util.getInstance(Util.java:381)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3515)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3447)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1951)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2554)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1761)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2046)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1964)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1949)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:147)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
        ... 36 more
  • 相关阅读:
    PHP 指定的 CGI 应用程序由于未返回完整的一组 HTTP 头而产生错误行为。
    BPM触发事件
    封装继承多态到底讲的是什么
    .Net 为什么叫.Net 转载自 jerrylsxu 的博客
    C# 琐碎记忆 Message
    SQL Case
    C# 命名规范(部分)
    C# 反射
    C# 日志 log 配置文件
    C# 琐碎记忆 三元表达式
  • 原文地址:https://www.cnblogs.com/bulrush/p/7806904.html
Copyright © 2011-2022 走看看