1

私は「予約」エンティティを「部分」エンティティと定義しました。それらの関係は1対多です。私の場合、そのような操作がありました

ステップ 1: FK で 1 つの予約を取得します。この予約の下にあると仮定します。3 つの部分があり、UI に表示されます。

ステップ 2: UI で、新しいパーツを 1 つ追加し、元の 3 つの保存済みパーツを削除済みパーツとしてマークし、最後にこの予約を再度保存します。

バックエンドでは、保存ロジックを次のように処理します

まず、予約アクションの保存機能は次のとおりです

       public String save() throws Exception{
            booking = preSave(booking);
            booking = doSave(booking);
            booking = postSave(booking);
            return SUCCESS;
        }

doSave 関数は次のとおりです。

@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)
        private Booking doSave(Booking booking) throws Exception{
            logger.debug("save booking start,will delete to be deleted/update/save record in DB");
            //Step 1:Get booking DAO from spring context
            BookingDAO dao  = (BookingDAO) DAOFactory.getDAO("Booking");
            //Step 2:Get the to be deleted object from booking tree,as usual,the to be deleted object is marked in UI
            List toBeDeleted = BookingUtil.handleDeletedObj(booking);
             logger.debug("The to be deleted object is ["+toBeDeleted+"]");
             //Step 3:If to be deleted object is not empty,invoke booking DAO's delete function to delete them
             if(toBeDeleted!=null && toBeDeleted.size()>0){
                  dao.delete(toBeDeleted);
             }
             //Step 4:Invoke booking DAO's save function to save/update obj
            booking = (Booking) dao.save(booking);
            return booking;
        }

DAOの削除機能

@Override
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)
public Object delete(Object object) {
    // TODO Auto-generated method stub
    logger.debug("delete to be deleted object ["+object+"]");
    if(object == null){
        logger.error("there is no to be deleted object found");
        return null;
    }
    Session session = sf.openSession();
    if(object instanceof  List){
        List list = (List) object;
        for(Object obj:list){
            session.delete(obj);
        }
        //session.flush();
        return list;
    }
    return object;
}

予約DAOの保存機能

@オーバーライド

@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)

public Object save(Object object) {
    logger.debug("save() start,save booking["+object+"] to DB");
    Booking booking = (Booking)object;
    String bookingNo = null;
    //Step 1:Check if booking no is empty,if empty,generate booking no by customer first
    if(booking.getBookingNo() == null || booking.getBookingNo().trim().isEmpty()){
        logger.debug("save(),find booking no is empty,will generate booking no first");
            bookingNo = (String) generateBookingNo(booking.getCustomer());
            //Set generated booking no to booking
            booking.setBookingNo(bookingNo);
    }
     //Step 2:Set part's FK bookingNo
    List <Part>parts = booking.getParts();
    if(parts!=null){
        for(Part part:parts){
            if(part.getBookingNo() == null || part.getBookingNo().isEmpty()){
                part.setBookingNo(booking.getBookingNo());
            }
        }
    }
    //Step 3:Set todoitem's FK
    List<ToDoItem>toDoItems = booking.getToDoItems();
    if(toDoItems!=null){
        for(ToDoItem toDoItem:toDoItems){
            if(toDoItem.getBookingNo() == null  || toDoItem.getBookingNo().isEmpty()){
                toDoItem.setBookingNo(booking.getBookingNo());
            }
        }
    }

    //Step 4:Save/update booking
    Session session = sf.getCurrentSession();
    session.saveOrUpdate(booking);
    session.flush();
    return booking;
}

ご覧のとおり、私のロジックは非常に単純です。ものを削除して保存します。この点を除けば、それらは 1 つのトランザクションである必要がありますが、テストを行うと、保存アクションの save() を呼び出した後に部品が削除されていないことがわかりました。まったく、ログは次のとおりです。

17:37:36,143 DEBUG BookingDAO:122 - delete to be deleted object [[com.chailie.booking.model.booking.Part@712e3058, com.chailie.booking.model.booking.Part@f681b75, com.chailie.booking.model.booking.Part@7be2a639]]
17:37:36,144 DEBUG SessionImpl:220 - opened session at timestamp: 13676602561
17:37:36,147 DEBUG DefaultDeleteEventListener:65 - entity was not persistent in delete processing
17:37:36,149 DEBUG VersionValue:44 - version unsaved-value strategy UNDEFINED
17:37:36,150 DEBUG IdentifierValue:104 - id unsaved-value: null
17:37:36,153 DEBUG DefaultDeleteEventListener:180 - deleting [com.chailie.booking.model.booking.Part#2]
17:37:36,154 DEBUG SessionImpl:1308 - setting cache mode to: GET
17:37:36,155 DEBUG SessionImpl:1308 - setting cache mode to: NORMAL
17:37:36,160 DEBUG SessionImpl:1308 - setting cache mode to: GET
17:37:36,162 DEBUG SessionImpl:1308 - setting cache mode to: NORMAL
17:37:36,162 DEBUG DefaultDeleteEventListener:65 - entity was not persistent in delete processing
17:37:36,163 DEBUG VersionValue:44 - version unsaved-value strategy UNDEFINED
17:37:36,163 DEBUG IdentifierValue:104 - id unsaved-value: null
17:37:36,164 DEBUG DefaultDeleteEventListener:180 - deleting [com.chailie.booking.model.booking.Part#3]
17:37:36,165 DEBUG SessionImpl:1308 - setting cache mode to: GET
17:37:36,165 DEBUG SessionImpl:1308 - setting cache mode to: NORMAL
17:37:36,166 DEBUG SessionImpl:1308 - setting cache mode to: GET
17:37:36,166 DEBUG SessionImpl:1308 - setting cache mode to: NORMAL
17:37:36,167 DEBUG DefaultDeleteEventListener:65 - entity was not persistent in delete processing
17:37:36,168 DEBUG VersionValue:44 - version unsaved-value strategy UNDEFINED
17:37:36,168 DEBUG IdentifierValue:104 - id unsaved-value: null
17:37:36,169 DEBUG DefaultDeleteEventListener:180 - deleting [com.chailie.booking.model.booking.Part#4]
17:37:36,170 DEBUG SessionImpl:1308 - setting cache mode to: GET
17:37:36,171 DEBUG SessionImpl:1308 - setting cache mode to: NORMAL
17:37:36,171 DEBUG SessionImpl:1308 - setting cache mode to: GET
17:37:36,172 DEBUG SessionImpl:1308 - setting cache mode to: NORMAL
17:37:36,173 DEBUG JDBCTransaction:103 - commit
17:37:36,174 DEBUG SessionImpl:337 - automatically flushing session
17:37:36,174 DEBUG JDBCContext:201 - before transaction completion
17:37:36,175 DEBUG SessionImpl:393 - before transaction completion
17:37:36,176 DEBUG JDBCTransaction:193 - re-enabling autocommit
17:37:36,177 DEBUG JDBCTransaction:116 - committed JDBC Connection
17:37:36,178 DEBUG JDBCContext:215 - after transaction completion
17:37:36,178 DEBUG ConnectionManager:296 - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
17:37:36,179 DEBUG SessionImpl:422 - after transaction completion
17:37:36,179 DEBUG SessionImpl:353 - automatically closing session
17:37:36,180 DEBUG SessionImpl:273 - closing session
17:37:36,180 DEBUG ConnectionManager:374 - performing cleanup
17:37:36,181 DEBUG ConnectionManager:435 - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
17:37:36,182 DEBUG JDBCContext:215 - after transaction completion
17:37:36,182 DEBUG ConnectionManager:296 - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
17:37:36,183 DEBUG SessionImpl:422 - after transaction completion
17:37:36,184 DEBUG SessionImpl:273 - closing session

しかし、DAO の delete() の予約の最後に session.flush() を追加すると、DB の一部が正常に削除される可能性があります。

私の質問は次のとおりです。DAOのdelete function()にflush()がなかった場合、なぜその部分を削除できないのですか?

Ps:私のセッション ファクトリのスプリング構成は次のとおりです。

bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource1" />
        </property>
        <property name="hibernateProperties">

            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.MySQLDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
                 <prop key="hibernate.transaction.flush_before_completion">true</prop>
                  <prop key="hibernate.transaction.auto_close_session">true</prop>
                   <prop key="hibernate.connection.release_mode">auto</prop>
                   <prop key="hibernate.hbm2ddl.auto">update</prop>
                   <prop key="format_sql">true</prop>
            </props>
        </property>
         <property name="packagesToScan">
               <list>
                    <value>com.chailie.booking.model.*</value>
                </list>
      </property>
4

0 に答える 0