在映射多对一时,Hibernate中不需要的行删除

时间:2013-01-13 17:34:21

标签: hibernate hibernate-mapping

我的hibernate应用程序中有以下映射。当我从此Booking表中删除一行时,将删除User和items表中的对应行。我使用hibernate Session的delete方法。我试过cascade =“all”和“none”。但他们都没有奏效。

我有一些用户和一些物品。每个用户可以有0 .. *行,每个项目在Booking表中都可以有0 .. *行!

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="my.hibernate.operations.Booking" table="testBooking" catalog="efeu">
        <id name="id" type="java.lang.Long">
            <column name="id" />
            <generator class="native" />
        </id>

        <many-to-one name="userID" column="user_id"
            not-null="true" class="my.hibernate.actors.User" />
        <many-to-one name="itemID" column="item_id" 
            not-null="true" class="my.hibernate.items.Item" />

        <property name="startDate" type="java.sql.Date" not-null="true">
            <column name="start_date" length="10" />
        </property>

        <property name="endDate" type="java.sql.Date">
            <column name="end_date" length="10" />
        </property>
    </class>
</hibernate-mapping>

它给我带来了以下错误:

org.hibernate.exception.ConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`efeu`.`testbooking`, CONSTRAINT `FKEC7473671463A66C` FOREIGN KEY (`user_id`) REFERENCES `testuser` (`id`))
    org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:128)
    org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
    org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    $Proxy8.executeUpdate(Unknown Source)
    org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
    org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3134)
    org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3337)
    org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:100)
    org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:280)
    org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
    org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1214)
    org.hibernate.internal.SessionImpl.forceFlush(SessionImpl.java:1233)
    org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:182)
    org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
    org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:757)
    org.hibernate.internal.SessionImpl.save(SessionImpl.java:749)
    org.hibernate.internal.SessionImpl.save(SessionImpl.java:745)
    my.hibernate.items.ItemDAO.save(ItemDAO.java:35)
    actions.subscriber.BookItem.cancellBooking(BookItem.java:118)
    actions.subscriber.BookItem.execute(BookItem.java:101)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    interceptors.LoginInterceptor.intercept(LoginInterceptor.java:52)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)

root cause

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`efeu`.`testbooking`, CONSTRAINT `FKEC7473671463A66C` FOREIGN KEY (`user_id`) REFERENCES `testuser` (`id`))
    com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
    com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2870)
    com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
    com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1169)
    com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:693)
    com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1404)
    com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1318)
    com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1303)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    $Proxy8.executeUpdate(Unknown Source)
    org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
    org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3134)
    org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3337)
    org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:100)
    org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:280)
    org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
    org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1214)
    org.hibernate.internal.SessionImpl.forceFlush(SessionImpl.java:1233)
    org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:182)
    org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
    org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:757)
    org.hibernate.internal.SessionImpl.save(SessionImpl.java:749)
    org.hibernate.internal.SessionImpl.save(SessionImpl.java:745)
    my.hibernate.items.ItemDAO.save(ItemDAO.java:35)
    actions.subscriber.BookItem.cancellBooking(BookItem.java:118)
    actions.subscriber.BookItem.execute(BookItem.java:101)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    interceptors.LoginInterceptor.intercept(LoginInterceptor.java:52)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)

无论如何,由于请求我复制了所有表的结构,但是我知道它不是必需的!注意!这些表由Hibernate自动生成!

CREATE TABLE `testuser` (
  `id` bigint(20) NOT NULL,
  `user_type` varchar(8) NOT NULL,
  `username` varchar(30) DEFAULT NULL,
  `password` varchar(128) DEFAULT NULL,
  `forename` varchar(128) DEFAULT NULL,
  `surname` varchar(128) DEFAULT NULL,
  `userlevel` varchar(30) DEFAULT NULL,
  `email` varchar(120) DEFAULT NULL,
  `phone_number` varchar(25) DEFAULT NULL,
  `address` varchar(150) DEFAULT NULL,
  `regDate` datetime DEFAULT NULL,
  `birthday` datetime DEFAULT NULL,
  `payable` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `testbooking` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `item_id` bigint(20) NOT NULL,
  `start_date` date DEFAULT NULL,
  `end_date` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKEC747367A12BE486` (`item_id`),
  KEY `FKEC7473671463A66C` (`user_id`),
  CONSTRAINT `FKEC7473671463A66C` FOREIGN KEY (`user_id`) REFERENCES `testuser`
(`id`),
  CONSTRAINT `FKEC747367A12BE486` FOREIGN KEY (`item_id`) REFERENCES `testitem`
(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

CREATE TABLE `testitem` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `item_type` varchar(8) NOT NULL,
  `title` varchar(30) DEFAULT NULL,
  `author` varchar(128) DEFAULT NULL,
  `item_status` varchar(30) DEFAULT NULL,
  `publication_date` datetime DEFAULT NULL,
  `publisher` varchar(80) DEFAULT NULL,
  `language` varchar(3) DEFAULT NULL,
  `duration` int(11) DEFAULT NULL,
  `trackNumber` int(11) DEFAULT NULL,
  `pages_number` int(11) DEFAULT NULL,
  `edition` int(11) DEFAULT NULL,
  `isbn` bigint(20) DEFAULT NULL,
  `serial_number` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1;

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,BookingUser实体和Item实体之间的联结实体。根据实体名称判断,User是该关系的所有者。

在这种情况下,User实体的Hibernate映射应如下所示: -

<hibernate-mapping>
    <class name="...User" ...>
        <id name="id" column="user_id">
            <generator class="native"/>
        </id>

        <set name="bookings" inverse="true" cascade="all-delete-orphan">
            <key column="user_id"/>
            <one-to-many class="Booking"/>
        </set>

        ...
    </class>
</hibernate-mapping>

User实体看起来像这样: -

public class User {

    private Long id;
    private Collection<Booking> bookings = new HashSet<Booking>();
    ...

    // assuming if you want to create bi-directional relationship between User and Booking
    public void addBooking(Booking booking) {
        booking.setUser(this);
        bookings.add(booking);
    }

    // getters and setters
    ...
}

要从用户中删除预订,而不是直接从Booking实体删除预订,您需要这样做: -

  • 首先,您先获取用户对象,例如:session.load(User.class, <someUserId>);
  • user.getBookings()集合中找到并删除预订对象。
  • 更新用户对象(session.saveOrUpdate(user);),级联将自动从Booking表中删除该条目。