gpt4 book ai didi

java - 使用 jUnit 在 Hibernate 中使用 Spring 魔术更新实体

转载 作者:行者123 更新时间:2023-11-30 09:10:23 29 4
gpt4 key购买 nike

我有一个 Web 项目,其中使用 Spring 3.1.1.RELEASE,Hibernate 4.2.0.Final,mysql version '5.5 .19-enterprise-commercial-advanced-log' 和 junit 4.7

我正在做我的单元测试,我测试我的 CRUD 操作。

我做了几次测试,几乎都没有问题,问题出在group-event关系上,在更新测试中,我想创建一个group和许多事件,设置列表(严格意义上的HashSet)将组发送到服务,更新方法也是如此。 创建工作正常,但不能更新 :(

public class Group implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

private Integer groupID;
private User user;
private Integer userID;
private User userManegement;
private Integer userManagementID;
private Date deteIni;
private Set<Event> events;
private Set<StatusGroup> status;

//get
//set
....

public class Event implements Serializable{

/**
*
*/
private static final long serialVersionUID = 1L;

private Integer eventID;
private Integer groupID;
private Date dateIni;
private Date dateTwo;
private String help;
private String commet;
private Group group;
//get
//set
......

映射

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 18/03/2014 09:58:25 AM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.my.dev.mysql.Group" table="Group">
<id name="groupID" type="java.lang.Integer">
<column name="id_group" />
<generator class="identity" />
</id>
<many-to-one name="user" column="user_id" foreign-key="id_user" class="com.my.dev.mysql.User"
fetch="join" update="false" insert="false">
</many-to-one>
<property name="userID" type="java.lang.Integer">
<column name="user_id" />
</property>
<many-to-one name="userManegement" column="user_management_id" foreign-key="id_user" class="com.my.dev.mysql.User"
fetch="join" update="false" insert="false">
</many-to-one>
<property name="userManagementID" type="java.lang.Integer">
<column name="user_management_id" />
</property>
<property name="deteIni" type="java.util.Date">
<column name="dete_ini" sql-type="DATE" not-null="true" />
</property>

<set name="events">
<key>
<column name="group_id" />
</key>
<one-to-many class="com.my.dev.mysql.Event" />
</set>
<set name="status">
<key>
<column name="group_id" />
</key>
<one-to-many class="com.my.dev.mysql.StatusGroup" />
</set>
</class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 18/03/2014 09:58:25 AM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.my.dev.mysql.Event" table="EVENT">
<id name="eventID" type="java.lang.Integer">
<column name="id_event" />
<generator class="identity" />
</id>
<property name="groupID" type="java.lang.Integer" not-null="true">
<column name="group_id" />
</property>
<property name="dateIni" type="java.util.Date" not-null="true">
<column name="date_ini" sql-type="TIMESTAMP" not-null="true" />
</property>
<property name="dateTwo" type="java.util.Date" not-null="true">
<column name="date_two" sql-type="TIMESTAMP" not-null="true" />
</property>
<property name="help" type="java.lang.String">
<column name="help" not-null="true" />
</property>
<property name="commet" type="java.lang.String">
<column name="commet" not-null="true" />
</property>
<many-to-one name="group" column="group_id" foreign-key="id_group" class="com.my.dev.mysql.Group"
fetch="join" update="false" insert="false">
</many-to-one>
</class>
</hibernate-mapping>

我的单元测试

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ TransactionalTestExecutionListener.class, DependencyInjectionTestExecutionListener.class })
@ContextConfiguration(locations = { "/testEnvironment.xml" })
public class GroupServiceImplTest {

@Autowired
private GroupService groupService;

@Test //THIS TEST WORKS FINE
public void create() {

FormBeanGroup form = new FormBeanGroup();
form.setDate("24/03/2014");

List<Event> events = new ArrayList<Event>();
for (int i = 0; i < 8; i++) {
Event event = new Event();
event.setHelp("help -" + Randomizer.getNumSRandom());
event.setDateTwo(Calendar.getInstance().getTime());

Calendar now = Calendar.getInstance();
now.set(Calendar.DAY_OF_YEAR, now.get(Calendar.DAY_OF_YEAR) - i);
event.setDate(now.getTime());
event.setCommet("ubicacion ");

events.add(event);
}

form.setEvents(events);

try {
groupService.save(form);
} catch (GenericException e) {

e.printStackTrace();
}

}


@Test //THIS TEST WORKS FINE
public void get(){
Group group = groupService.getById(40);
System.out.println(group);
assertNotNull(group);

assertEquals(group.getStatus().get() , TypeGroup.ALFA);
}


@Test //THIS TEST WORKS FINE
public void delete(){
groupService.borrarEvents(41);
}

@Test // f*****in TEST
public void update() {

FormaCapturaGroup form = new FormaCapturaGroup();
form.setDate("24/03/2014");
form.setId(40);

List<Event> events = new ArrayList<Event>();
// for (int i = 0, k = 250; i < 8; i++, k++) { //fill events, but i comment, trying to find the error

form.setEvents(events);

try {
groupService.update(form);
} catch (GenericException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

服务

@Transactional
public void update(FormBeanGroup form) throws GenericException {
Group group = groupDao.getById(form.getId());
if (group != null) {

//more code comment beacuse i trying to find the error


group.setEvents(new HashSet<Event>(form.getEvents())); //fix chrome grammar spelling


groupDao.update(group);
System.out.println("post");
}
}

public Group update(com.segurosargos.siga.modelo.mysql.Group group)
throws GenericException {

System.out.println("DAO{Update} ");
System.out.println(group);

//really 100 lines commet
//Believe me seriously.
//this is all code in update method

return null;
}

当我运行测试更新时抛出这个错误:

org.springframework.dao.DataIntegrityViolationException: could not perform addBatch; SQL [update EVENT set group_id=null where group_id=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not perform addBatch
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:159)
at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:606)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:488)
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.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy18.update(Unknown Source)
at com.my.dev.service.impl.GroupServiceImplTest.update(AgendaServiceImplTest.java:129)
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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
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.exception.ConstraintViolationException: could not perform addBatch
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:128)
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.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:114)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:101)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:149)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:198)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:357)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:277)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:328)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1233)
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 org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:480)
... 36 more
Caused by: java.sql.BatchUpdateException: Column 'group_id' cannot be null
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1666)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1082)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:110)
... 48 more

并记录

post
Hibernate:
update
EVENT
set
group_id=null
where
group_id=?
WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1048, SQLState: 23000
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Column 'group_id' cannot be null

是的 group_idNOT NULL为什么会发生此更新?

虽然测试我的代码评论很多,但每次产生这个异常时,他都将其归因于我所做的事情。但不是。

事实上,将列更改为接受 null,并且我的测试运行良好,在我的单元测试和数据库中都重述了正确的事情。

我一直想知道为什么会这样,我从来没有做过这个神奇的更新,这是我做错了什么,我需要你的帮助。

最佳答案

问题是当这条指令被执行时:

group.setEventos(new HashSet<Evento>(form.getEventos()));

有新事件链接到该组。这意味着之前链接到该组的事件不再与其相关联。

为了断开数据库中的这个链接,Hibernate 需要将外键 EVENT.group_id 更新为 null,这就是进行更新的原因。

之前链接到组的事件将作为数据库中的独立实体继续存在,而不会附加到任何组。

这是因为 Event 是一个 @Entity 而不是一个 @Embeddable,所以它可以在不与 相关的情况下存在组。但是将外键列设置为不可为空的类型违背了这一点,并导致 Hibernate 尝试更新不可为空的列。

然后需要更新映射以使 Event 成为没有组就不能存在的 @Embeddable,或者将外键声明为可为 null。

关于java - 使用 jUnit 在 Hibernate 中使用 Spring 魔术更新实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22570163/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com