大体是这样子的思路:Forum 1:n Course Course 1:nTopic Topic 1:n Reply 一张的,我成功过。所以我想引入两张的,然后JUnit 测试数据竟然过不了。 2014-12-23 18:31:03,550 ERROR [org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:324)] – Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2dd4708d] to prepare test instance [cn.edu.fjnu.java1.cdio2.yplan.service.ForumServiceTest@5629507c] |
|
40分 |
容器貌似都没加载成功,实体配置有问题吧?贴出代码看看
|
/** * */ package cn.edu.fjnu.java1.cdio2.yplan.domain; import java.util.Set; /** * 类的作用:论坛年级版块的实体类 * * @author chenjie * @version 1.0 * @创建时间 2014年12月17日 下午5:50:32 */ public class Forum { /**实体Forum的主键*/ private Long forumID; /**版块的名称*/ private String forumName; /**版块的描述*/ private String forumDescription; /**版块排序位置号*/ private int forumPosition; /**版块前置图片*/ private String mouseOutIconPath; /**版块后置图片*/ private String mouseOnIconPath; private Set<Course> courses; /** * */ public Forum() { super(); // TODO Auto-generated constructor stub } /** * @param forumID */ public Forum(Long forumID) { super(); this.forumID = forumID; } /** * @param forumName * @param forumDescription * @param forumPosition * @param mouseOutIconPath * @param mouseOnIconPath */ public Forum(String forumName, String forumDescription, int forumPosition, String mouseOutIconPath, String mouseOnIconPath) { super(); this.forumName = forumName; this.forumDescription = forumDescription; this.forumPosition = forumPosition; this.mouseOutIconPath = mouseOutIconPath; this.mouseOnIconPath = mouseOnIconPath; } /** * @return the forumID */ public Long getForumID() { return forumID; } /** * @param forumID the forumID to set */ public void setForumID(Long forumID) { this.forumID = forumID; } /** * @return the forumName */ public String getForumName() { return forumName; } /** * @param forumName the forumName to set */ public void setForumName(String forumName) { this.forumName = forumName; } /** * @return the forumDescription */ public String getForumDescription() { return forumDescription; } /** * @param forumDescription the forumDescription to set */ public void setForumDescription(String forumDescription) { this.forumDescription = forumDescription; } /** * @return the forumPosition */ public int getForumPosition() { return forumPosition; } /** * @param forumPosition the forumPosition to set */ public void setForumPosition(int forumPosition) { this.forumPosition = forumPosition; } /** * @return the mouseOutIconPath */ public String getMouseOutIconPath() { return mouseOutIconPath; } /** * @param mouseOutIconPath the mouseOutIconPath to set */ public void setMouseOutIconPath(String mouseOutIconPath) { this.mouseOutIconPath = mouseOutIconPath; } /** * @return the mouseOnIconPath */ public String getMouseOnIconPath() { return mouseOnIconPath; } /** * @param mouseOnIconPath the mouseOnIconPath to set */ public void setMouseOnIconPath(String mouseOnIconPath) { this.mouseOnIconPath = mouseOnIconPath; } /** * @return the courses */ public Set<Course> getCourses() { return courses; } /** * @param courses the courses to set */ public void setCourses(Set<Course> courses) { this.courses = courses; } /** * 重写toString方法 */ @Override public String toString() { return "Forum [forumID=" + forumID+",forumName=" + forumName +",forumDescription=" + forumDescription + ",forumPosition=" + forumPosition + ",mouseOutIconPath=" + mouseOutIconPath + ",mouseOnIconPath=" + mouseOnIconPath + "]"; } } /** * */ package cn.edu.fjnu.java1.cdio2.yplan.domain; import java.util.Set; import com.sun.org.apache.xpath.internal.FoundIndex; /** * @author chenjie * @version 1.0 * @创建时间 2014年12月21日 上午10:28:48 */ public class Course { /**实体Course的主键*/ private Long courseID; /**课程名称*/ private String courseName; /**课程所属年级*/ private Forum forum; private Set<Topic> topics; /** * */ public Course() { } /** * @param courseName * @param forum */ public Course(String courseName, Forum forum) { super(); this.courseName = courseName; this.forum = forum; } /** * @param courseID */ public Course(Long courseID) { super(); this.courseID = courseID; } //*******************************setter和getter***************************** /** * @return the courseID */ public Long getCourseID() { return courseID; } /** * @param courseID the courseID to set */ public void setCourseID(Long courseID) { this.courseID = courseID; } /** * @return the courseName */ public String getCourseName() { return courseName; } /** * @param courseName the courseName to set */ public void setCourseName(String courseName) { this.courseName = courseName; } /** * @return the forum */ public Forum getForum() { return forum; } /** * @param forum the forum to set */ public void setForum(Forum forum) { this.forum = forum; } /** * @return the topics */ public Set<Topic> getTopics() { return topics; } /** * @param topics the topics to set */ public void setTopics(Set<Topic> topics) { this.topics = topics; } /** * 覆写Course的toString方法 * */ @Override public String toString() { return "Course [ courseID = " + courseID + ",courseName = " + courseName + ",Forum = " + forum.getForumID(); } } /** * */ package cn.edu.fjnu.java1.cdio2.yplan.domain; import java.util.Date; import java.util.Set; /** * 继承实体类Article * @author chenjie * @version 1.0 * @创建时间 2014年12月22日 下午2:39:02 */ public class Topic extends Article { /** 普通帖 */ //public static final int TYPE_NORMAL = 0; /** 精华帖 */ //public static final int TYPE_BEST = 1; /** 置顶帖 */ //public static final int TYPE_TOP = 2; /**帖子的类型*/ private int topicType; /**帖子所属的科目*/ private Course course; /**帖子下的回复*/ //private Set<Reply> replies; // /**帖子最后的回复者*/ //private User user; /**帖子最后的回复时间*/ //private Date topicLastReplyTime; /**帖子回复的数量*/ //private int topicReplyCount; /** * */ public Topic() { super(); // TODO Auto-generated constructor stub } /** * @param id */ public Topic(Long id) { super(id); // TODO Auto-generated constructor stub } /** * @param topicType * @param course */ public Topic(int topicType, Course course) { super(); this.topicType = topicType; this.course = course; } /** * @return the topicType */ public int getTopicType() { return topicType; } /** * @param topicType the topicType to set */ public void setTopicType(int topicType) { this.topicType = topicType; } /** * @return the course */ public Course getCourse() { return course; } /** * @param course the course to set */ public void setCourse(Course course) { this.course = course; } } 以上是3个实体,关系如1楼所说 |
|
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.edu.fjnu.java1.cdio2.yplan.domain"> <class name="Forum"> <!-- 主键id --> <id name="forumID"> <!-- 主键采用自增长的方式 --> <generator class="native" /> </id> <!-- 年级版块的名称 --> <property name="forumName" /> <!-- 年级版块的描述 --> <property name="forumDescription" /> <!-- 年级版块的排序位置 --> <property name="forumPosition" /> <!-- 动态效果前置图(暂定) --> <property name="mouseOnIconPath" /> <!-- 动态效果后置图(暂定)properties的作用 --> <property name="mouseOutIconPath" /> <set name="courses" cascade="delete"> <key column="forumID"></key> <one-to-many class="Course"></one-to-many> </set> </class> </hibernate-mapping> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.edu.fjnu.java1.cdio2.yplan.domain"> <class name="Course" lazy="false"> <!-- 主键id --> <id name="courseID"> <!-- 主键采用自增长的方式 --> <generator class="native" /> </id> <!-- 课程名 --> <property name="courseName" /> <!-- 所属年级版块ID --> <!-- forum属性,本类与Forum的多对一 ,一个版块包含多个帖子--> <many-to-one name="forum" class="Forum" column="forumID"></many-to-one> <set name="topics" cascade="delete"> <key column="courseID"></key> <one-to-many class="Topic" ></one-to-many> </set> </class> </hibernate-mapping> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.edu.fjnu.java1.cdio2.yplan.domain"> <class name="Topic" lazy="false"> <!-- 主键id --> <id name="id"> <!-- 主键采用自增长的方式 --> <generator class="native" /> </id> <!-- 帖子标题 --> <property name="title" /> <!-- 帖子内容 --> <property name="content" type="text" length="20000"/> <!-- 帖子发表时间 --> <property name="postTime" type="timestamp"/> <!-- 帖子作者发帖时的ip地址 --> <property name="ipAddr"/> <property name="topicType"/> <!-- 所属课程的课程ID --> <!-- course属性,本类与Course的多对一 ,一个课程下包含多个帖子--> <many-to-one name="course" class="Course" column="courseID"></many-to-one> </class> </hibernate-mapping> 以上三个文件是 数据库映射 xml配置文件 |
|
现在的一个问题是,我现在用junit测试,前面两张 forumTest 和courseTest测试都成功通过,并且在mysql建起表有数据,然后topicTest 能够建表,但是空数据。并且报错: org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: cn.edu.fjnu.java1.cdio2.yplan.domain.Course; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cn.edu.fjnu.java1.cdio2.yplan.domain.Course at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:654) at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at com.sun.proxy.$Proxy11.save(Unknown Source) at cn.edu.fjnu.java1.cdio2.yplan.service.TopicServiceTest.testSave(TopicServiceTest.java:40) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) 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: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cn.edu.fjnu.java1.cdio2.yplan.domain.Course at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243) at org.hibernate.type.EntityType.getIdentifier(EntityType.java:456) at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:265) at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:275) at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:295) at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3403) at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:520) at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:230) at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:154) at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219) at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656) ... 38 more |
|
save the transient instance before flushing: cn.edu.fjnu.java1.cdio2.yplan.domain.Course
把主控端的cascade 属性修改为”save-update”试试 |
|
问题已经解决了,太大意了。 |