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
hibernate ?多对多
原文地址:http://www.cnblogs.com/bulrush/p/7806904.html