我想在保存spring数据之前能够使用一些更复杂的保存逻辑。
我有这个JpaRepository:
public interface MyClassRepository extends JpaRepository<MyClass, Long> {
@Query("from com.package.MyClass as myClass where myClass.parent is null");
MyClass getRootMyClass();
...
}
而这个实体:
@Entity
@Table("MY_CLASS")
public class MyClass {
@ManyToOne
@JoinColumn("parent_id")
MyClass parent;
}
我希望能够为父属性检查null,并在存储库中设置root myClass。例如,像这样:
if(myClass.getParent() == null) {
myClass.setParent(getRootMyClass());
}
我不能使用实体中的@PrePersist
钩子,因为它不知道存储库。我不能在存储库中这样做,因为它是一个接口 - 而不是一个类。把它放在哪里最好的地方?
如果您使用的是JDK 8,则可以将以下方法添加到qazxsw poi中:
MyClassRepository
然后,你应该调用checkSave()而不是save()
您可以使用Hibernate的public interface MyClassRepository extends JpaRepository<MyClass, Long> {
@Query("from com.package.MyClass as myClass where myClass.parent is null")
MyClass getRootMyClass();
default void checkSave(MyClass myClass) {
if (myClass.getParent() == null) {
myClass.setParent(getRootMyClass());
}
save(myClass);
}
}
,您可以为Hibernate的每个PreInsertEventListener
操作注册这样的拦截器;
prePersist
这种方法背后的想法是,Hibernate中的所有持久性事件都将被拦截,例如,如果存在一些级联插入,这仍然会触发。因此,该解决方案涵盖了@Component
public class MyEventListener implements PreInsertEventListener {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private MyClassRepository myClassRepository;
@PostConstruct
private void init() {
SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(this);
}
@Override
public boolean onPreInsert(PreInsertEvent preInsertEvent) {
if (MyClass.class.equals(preInsertEvent.getEntity().getClass())) {
MyClass entity = (MyClass) preInsertEvent.getEntity();
if(myClass.getParent() == null) {
myClass.setParent(myClassRepository.getRootMyClass());
}
}
return false;
}
}
的所有可能的持久性,如果这对您的要求太多,则更优选其他更简单的解决方案。