下面是场景:
@Entity
@Table(name = "Item")
public class Item implements java.io.Serializable {
private Integer itemId; //Auto Genenerated Unique ID
private String item; //Item description
private Set<ItemContainer> itemContainers = new HashSet<ItemContainer>(0); //Set of ItemContainers
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "item", orphanRemoval = true)
public Set<ItemContainer> getItemContainers() {
return this.itemContainers;
}
}
@Entity
@Table(name = "ItemContainer")
public class ItemContainer implements java.io.Serializable {
private Integer itemContainerId; //Auto Genenerated Unique ID
private Item item; //Item link
private Container container; //Container link
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "itemId")
public Item getItem() {
return this.item;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "containerId")
public Container getContainer() {
return this.container;
}
}
@Entity
@Table(name = "Container")
public class Container implements java.io.Serializable {
private Integer containerId; //Auto Genenerated Unique ID
private String container; //description
private Set<ItemContainer> itemContainers = new HashSet<ItemContainer>(0);
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "container", orphanRemoval = true)
public Set<ItemContainer> getItemContainers() {
return this.itemContainers;
}
}
容器和项都可以存在排他性。ItemContainer只能包含对现有项和容器的引用
我想要做的是能够删除一个项目,并删除它对应的ItemContainer行(使用孤儿删除)。任何容器都应该仍然存在。
@Override
public void delete(Item item) {
EntityManager em = getEntityManager();
em.remove(em.contains(item) ? item: em.merge(item));
}
编辑1:正如JB所要求的:下面是正在使用的相关代码。
请求来自一个jsp
/deleteItem?itemId=${item.itemId}
值得一提的是,我试图在我的jUnit测试中做同样的事情(如果需要,我可以发布测试代码和任何相关的类),但是我没有收到错误(它通过时没有抛出FK约束错误,但是ItemContainer表仍然包含对已删除项的引用)。
@Controller
public class ItemController {
@Autowired
private ItemsService itemsService;
@RequestMapping(value = "/deleteItem")
public String deleteItem(@RequestParam() int itemId) {
itemsService.delete(itemId);
return "redirect:systemSettings/items";
}
}
@Service("itemsService")
public class ItemsService {
@Autowired
private ItemsDAO itemsDao;
public void delete(int itemId) {
itemsDao.delete(itemsDao.getItem(itemId));
}
}
@Repository
@Transactional
@Component("itemsDao")
public class ItemsDAOImpl implements ItemsDAO {
@PersistenceContext
private EntityManager entityManager;
@Override
public EntityManager getEntityManager() {
return entityManager;
}
@Override
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public Item getItem(int itemId) {
String queryString = "SELECT i FROM Item i "
+ "LEFT JOIN FETCH i.itemMachines "
+ "WHERE i.itemId=:itemId";
Query query = getEntityManager().createQuery(queryString);
query.setParameter("itemId", itemId);
Item item = (Item) query.getSingleResult();
System.out.println(item.getItemMachines().size());
return item;
}
@Override
public void delete(Item item) {
EntityManager em = getEntityManager();
em.remove(em.contains(item) ? item : em.merge(item));
}
}
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:189)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:155)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:519)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy29.delete(Unknown Source)
at com.home.myproject.service.ItemsService.delete(ItemsService.java:45)
at com.home.myproject.service.ItemsService$$FastClassBySpringCGLIB$$788e7765.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:640)
at com.home.myproject.service.ItemsService$$EnhancerBySpringCGLIB$$296a7299.delete(<generated>)
at com.home.myproject.controllers.ItemController.deleteItem(ItemController.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3400)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3630)
at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:114)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:515)
... 50 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The DELETE statement conflicted with the REFERENCE constraint "FK_ItemContainer_Item". The conflict occurred in database "MyDatabase2", table "dbo.ItemContainer", column 'itemId'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(Unknown Source)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(Unknown Source)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
... 64 more
发现这个问题JPA级联移除孤儿-James的答案证实了JB所说的,但仍然不知道为什么它不能工作:(
第一个想法(结果是错误的,请检查编辑以获得解决方案)
好了,我已经找到这个问题的答案了。
首先让我介绍一下解决方案的上下文(和问题,因为我仍然有点困惑)。
通过MS SQLServer Management Studio将两个外键设置为级联删除可以解决此问题。我现在可以删除一个项目,并让它正确地删除链接它们的ItemContainer记录。
编辑1:
--------------------------------------------------
既然有了新的html" target="_blank">消息,我想我会更新这个。
这是我的职能
public void delete(int itemId) {
itemsDao.delete(itemsDao.getItem(itemId));
}
注意:
1。来自DAO
2的服务请求项。DAO将项返回给服务
3。服务将项目传递给DAO
将@transaction
添加到此方法中(或将其完全从DAO中移除并将其放入服务类)可以修复该问题。
问题内容: 我有两个分别以双向一对多关系存在的实体类 A 和 B。 A.java: B.java 在一个简单的控制台应用程序中,我从数据库中获取了特定的 A 行,并尝试删除其详细信息 B 行(随机),但是 JPA / Hibernate* 不仅删除了该行-甚至没有向该行发出任何 DELETE 语句。数据库。删除 B 行的唯一方法是从 A.java 的集合( LinkedHashSet )中删除相应
我试图在类别和发布类(OneToMany)之间建立关系,我需要删除所有属于特定类别的发布。我不知道我是否遗漏了一些注释,但这是我在执行查询时的错误: org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常org.hibernate.exception.ConstraintViolationException:无法执行更新查询o
我正在尝试删除一个父/子自连接实体,但无法这样做,这里是我的映射
主要内容:JPA实体删除示例要从数据库中删除记录,可以使用接口提供方法。方法使用主键来删除特定的记录。 JPA实体删除示例 在这里,我们将演示如何根据主键删除指定学生的信息。 完整的项目代码如下所示 - 这个例子包含以下步骤 - 第1步: 在包下创建一个名为的实体类,它包含属性:,和。 文件:StudentEntity.java 的代码如下 - 第2步: 将实体类和其他数据库配置映射到文件中。 文件:persistence.
举一个非常简单的一对多关系的例子(国家 实体的方法: 应该注意,<code>orphanRemove</code>设置为<code>true</code>。<code>StateTable</code>实体由一个客户端应用程序提供,该应用程序有兴趣将<code>State Table</code>中的实体关联<code>Country</code<(<code>countryId=67</code
问题内容: 我有以下通常正常工作的代码: 对于我的许多实体类来说,这都是可行的。但是对于其中的两个它什么也不做,它不会引发任何异常,也不会删除该对象。来自hibernate的日志显示,hibernate执行了许多选择查询,但它甚至没有尝试执行删除。 我已经在这里和这里尝试了在其他类似问题中发现的建议,但是没有用(嗯,后者建议我不能使用,但是我只是在和之间加上了语句)。 我似乎找不到这两个类比其他类