MySQL触发器通过直接插入工作,但在通过Hibernate提交时不工作



我有以下片段,我们使用它将实体持久化到我们的数据库中:

private void singleStatusChange( Employee employee , OrderStatusType type , String comment , String classification ){
try( CloseableEntityManager em = HibernateUtil.getEntityManager() ){
em.beginTransaction();
OrderStatusChangeRequest orderStatusChangeRequest = new OrderStatusChangeRequest();
orderStatusChangeRequest.setOrder( em.getEntityReferenceById( Order.class , this.getId() ) );
orderStatusChangeRequest.setOrderStatusType( type );
orderStatusChangeRequest.setEmployee( employee );
orderStatusChangeRequest.setComment( comment );
orderStatusChangeRequest.setClassification( classification );
//When this entry is being persisted a BEFORE INSERT Trigger is activated and 1.- Check if status change is feasible, 2.- Expire all previous order statuses, 3.- Updates order lastHandledBy
em.persist( orderStatusChangeRequest );
em.commit();
}catch ( Exception e ){
e.printStackTrace();
throw new InvalidOrderStatusChangeException( e );
}
}

当这种情况发生时,BEFORE INSERT上会触发一个触发器,负责处理我们应用程序的额外业务逻辑。除了一句话之外,所有的东西都完成了,我不完全确定为什么会这样。这是我们的触发器:

CREATE DEFINER=`gofarma`@`%` TRIGGER OrderStatusChangeRequestsBeforeInsert
BEFORE INSERT
ON OrderStatusChangeRequests FOR EACH ROW
BEGIN
SELECT COUNT(1) INTO @IsNewStatusPossible FROM OrderStatusTypeFlows ostf WHERE ostf.`To` = NEW.Status AND ostf.`From` IS NULL ;
SELECT COUNT(1) INTO @IsPossible FROM OrderStatusTypeFlows ostf WHERE ostf.`To` = NEW.Status AND ostf.`From` = ( SELECT o.Status FROM Orders o WHERE o.ID = NEW.`Order` LIMIT 1 );
SELECT COUNT(1) INTO @IsImpossible FROM OrderStatusTypeFlows ostf WHERE ostf.`To` = NEW.Status AND ostf.`NeverIfThisPresent` IN ( SELECT `OrderStatusType` FROM OrderHistoryEntries WHERE `Order` = NEW.`Order` ) ;
SELECT COUNT(1) INTO @IsAdmin FROM Employees e LEFT JOIN EmployeeRoles er ON e.ID = er.EmployeeID LEFT JOIN Roles r ON er.RoleID = r.ID
WHERE r.IsAdmin AND e.ID = NEW.Employee;
IF( ( ( @IsPossible = 0 AND @IsNewStatusPossible = 0 ) OR @IsImpossible > 0 ) AND @IsAdmin = 0 ) THEN
SIGNAL SQLSTATE '12345' set message_text='com.gofarma.olimpo.exceptions.InvalidOrderStatusChangeException';
END IF;
UPDATE OrderHistoryEntries os SET os.EffectiveTo = CURRENT_TIMESTAMP WHERE os.`Order` = NEW.`Order` AND os.EffectiveTo > CURRENT_TIMESTAMP;
INSERT INTO OrderHistoryEntries
(ID, Comment, EffectiveFrom, EffectiveTo, OrderStatusType, PrescriptionAction, SystemFrom, SystemTo, `Type`, Employee, `Order`)
VALUES(UUID(), NEW.Comment, current_timestamp(), '9999-12-31 23:59:59', CASE
WHEN NEW.Status = 0 THEN 'NEW'
WHEN NEW.Status = 1 THEN 'PACKED'
WHEN NEW.Status = 2 THEN 'SENT'
WHEN NEW.Status = 3 THEN 'COMPLETED'
WHEN NEW.Status = 4 THEN 'CANCELED'
WHEN NEW.Status = 5 THEN 'UNKNOWN'
WHEN NEW.Status = 6 THEN 'COLLECTED'
WHEN NEW.Status = 7 THEN 'DELIVERED'
WHEN NEW.Status = 8 THEN 'PRECOMPLETED'
WHEN NEW.Status = 9 THEN 'RESENT'
WHEN NEW.Status = 10 THEN 'UNPAID'
WHEN NEW.Status = 11 THEN 'UNDELIVERED'
WHEN NEW.Status = 12 THEN 'PENDING'
WHEN NEW.Status = 13 THEN 'WAITING_FOR_ADVANCE'
WHEN NEW.Status = 14 THEN 'ADVANCE_PICKED'
WHEN NEW.Status = 15 THEN 'ADVANCE_NOT_PICKED'
END, NULL, current_timestamp(), '9999-12-31 23:59:59', 'ORDER_STATUS', NEW.Employee, NEW.`Order`);
UPDATE Orders o SET o.LastHandledBy = NEW.Employee , o.Status = NEW.Status WHERE o.ID = NEW.`Order`;
IF( NEW.Status IN ( 3 , 8 , 9 , 10 , 12 ) ) THEN
UPDATE Trips t JOIN TripOrders ot ON ot.TripID = t.ID JOIN DriverShifts ds ON ds.Driver = t.Driver
SET t.status = 1 , t.closeComment = NEW.Comment , t.arrivalTime = CURRENT_TIMESTAMP , t.realEndTime = COALESCE( t.realEndTime , CURRENT_TIMESTAMP ) , ds.AvailableSince = CURRENT_TIMESTAMP
WHERE ot.OrderID = NEW.`Order` AND t.Status = 0 AND !t.IsTransporter;
END IF;
IF( (SELECT `PrescriptionAction` FROM `Orders` `o` WHERE `o`.`ID` = NEW.`Order`) <> 0 AND NEW.`Status` = 8) THEN
UPDATE `Orders` `o` SET `o`.`PrescriptionNumber` = (
SELECT 
COALESCE(MAX(`PrescriptionNumber`),0)+1
FROM 
Orders
WHERE 
`PrescriptionAction` = `o`.`PrescriptionAction`
AND
`Branch` = `o`.`Branch`
GROUP BY `Branch`) WHERE `o`.`ID` = NEW.`Order`;
END IF;
END

未正确执行的位如下:

UPDATE Orders o SET o.LastHandledBy = NEW.Employee , o.Status = NEW.Status WHERE o.ID = NEW.`Order`;

所有其他内容都会插入并更新。但是,该语句根本不执行。只有当我们通过Hibernate持久化实体时,才会发生这种情况,如果我们要运行查询以将新条目插入OrderStatusChangeRequest表,那么一切都会按预期运行。我们缺了什么吗?hibernate.cfg.xml文件包含以下内容:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.provider_class">org.hibernate.hikaricp.internal.HikariCPConnectionProvider</property>
<property name="connection.pool_size">500</property>
<!--<property name="connection.autoReconnect">true</property>-->
<!--<property name="connection.autoReconnectForPools">true</property>-->
<property name="hibernate.dialect.storage_engine">innodb</property>
<!--<property name="connection.release_mode">ON_CLOSE</property>-->
<!--<property name="show_sql">true</property>-->
<!--<property name="hbm2ddl.auto">update</property>-->
<property name="hibernate.hikari.leakDetectionThreshold">30000</property>
<property name="hibernate.connection.autocommit">true</property>
</session-factory>
</hibernate-configuration>

作为附加信息,CloseableEntityManager只是EntityManager的包装器,它实现了Autoclosable:

public CloseableEntityManager beginTransaction() {
if (this.getTransaction().isActive()) return this;
this.getTransaction().begin();
return this;
}
public void commit() {
this.getTransaction().commit();
}
@Override
public void close() {
logger.debug( String.format("Entity Manager %s close call",this.id) );
if( this.entityManager == null ) return;
boolean isActive = this.entityManager.getTransaction().isActive();
if( isActive || readOnly ){
logger.debug( String.format("Entity Manager %s transaction was active, rolling back",this.id) );
this.entityManager.getTransaction().rollback();
}
this.entityManager.close();
}

正如问题评论所描述的,在我的案例中使用@DynamicUpdate是有效的。

最新更新