此问题在此处已有答案:
Refresh and fetch an entity after save (JPA/Spring Data/Hibernate)(5个答案)
两个月前关门了。
触发器工作正常,在脚本中执行时会生成值。在执行使用@Transactional注解保存的方法后,触发器生成的值为空。在数据库中检查时,此字段具有值。在执行保存方法后,我尝试使用findById刷新记录,但该字段仍为空。奇怪的是,当我运行API来获取执行相同findById方法的记录时,它会显示值。
我有另一个表的类似代码,它工作得很完美。不同的是在触发器中调用的函数比这个执行得更快。
@Transactional是否执行提交?当带有@Transaction注解的方法执行完成时,提交是否也完成?那么为什么执行findById时数据库记录与实体记录不相同?
以下是可供参考的示例代码片段:
@Entity
@Table(name = "my_table")
@EntityListeners(AuditingEntityListener.class)
public class MyTableEntity implements Serializable {
...
@Id
@GeneratedValue(generator = "iDGenerator")
@Column(name="column1", nullable=false, updatable=false)
private Long column1;
@Column(name="column2", length=5, nullable=false, updatable=false)
private String column2;
@Column(name="column3", length=10)
private String column3;
@Column(name="column4", insertable=false, updatable=false)
private Long column4;
@Column(name="cre_userid", length=30, nullable=false, updatable=false)
@CreatedBy
private String createdBy;
@Column(name="cre_date", nullable=false, updatable=false)
@CreatedDate
private LocalDateTime dateCreated;
...
它的数据表有一个触发程序,会设定column 4的值,如下所示:
CREATE OR REPLACE TRIGGER MY_TABLE_BIUFER
BEFORE INSERT ON MY_TABLE
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
BEGIN
:new.column4 := workflow_pkg.create_workflow (:new.column1);
END;
控制器和服务代码片段如下所示:
@Service
public class MyServiceImpl implements MyService{
@Autowired
MyTableRepository myTableRepo;
@Override
public MyTableDto getRecord(Long pk) {
MyTableDto returnValue;
MyTableEntity myTableEntity = myTableRepo.findById(pk)
.orElseThrow(() -> new IIBSException("Transaction Id " + pk + " not found. Process Terminated."));
myTableDto = convertToDto(myTableEntity); //use ModelMapper to convert entity to dto
return returnValue;
}
@Override
@Transactional
public Long saveRecord(MyTableDto myTableDto) {
MyTableEntity myTableEntity, storedDetails;
Long returnValue;
myTableEntity = convertToEntity(myTableDto); //use ModelMapper to convert dto to entity
storedDetails = myTableRepo.saveAndFlush(myTableEntity);
returnValue = storedDetails.getQuotApplTransNo();
return returnValue;
}
}
@RestController
@RequestMapping
public class MyController {
@Autowired
MyService myService;
@GetMapping(path="/{pk}")
public MyTableDto getRecord (@PathVariable Long pk) throws MyException {
if (pk == null) throw new MyException(ErrorMessage.MISSING_PARAMETER.getErrorMessage());
MyTableDto returnValue = myService.getRecord(pk);
return returnValue;
}
@PostMapping
public MyTableDto saveRecord (@RequestBody MyTableDto myTableDto) throws MyException
{
//.. validations .. //
Long pk = myService.saveRecord(myTableDto);
if (pk == null) throw new MyException("Error in saving Request for Quotation Package");
MyTableDto returnValue = myService.getRecord(pk);
return returnValue;
}
}
1条答案
按热度按时间vcirk6k61#
保存时,数据库表中的值不会同步回实体。
如果需要这些值,必须在保存后调用
EntityManager.refresh()
。JpaRepository上没有刷新,因此必须将
EntityManager
注入到服务中。