Mau*_*ari 31
只需像往常一样创建自定义界面,并在那里声明要使用与CrudRepository(或JpaRepository等)公开的方法相同的签名进行ovverride的方法.假设您有一个MyEntity实体和一个MyEntityRepository存储库,并且您希望覆盖默认的自动生成save方法,MyEntityRepository该方法只接受一个实体实例,然后定义:
public interface MyEntityRepositoryCustom {
<S extends MyEntity> S save(S entity);
}
Run Code Online (Sandbox Code Playgroud)
像MyEntityRepositoryImpl往常一样,在你的喜欢中实现这个方法:
@Transactional
public class MyEntityRepositoryImpl implements MyEntityRepositoryCustom {
public <S extends MyEntity> S save(S entity) {
// your implementation
}
}
Run Code Online (Sandbox Code Playgroud)
然后,像往常一样,让MyEntityRepository实施MyEntityRepositoryCustom.
这样做,Spring Data JPA将调用save您的方法MyEntityRepositoryImpl而不是默认实现.至少这对我来说适用delete于Spring Data JPA 1.7.2中的方法.
我想你扩展SimpleJpaRepository:
public class **CustomSimpleJpaRepository** extends SimpleJpaRepository {
@Transactional
public <S extends T> S save(S entity) { //do what you want instead }
}
Run Code Online (Sandbox Code Playgroud)
然后通过扩展来确保使用它而不是默认的SimpleJpaRepository:
public class CustomJpaRepositoryFactory extends JpaRepositoryFactory {
protected <T, ID extends Serializable> JpaRepository<?, ?> getTargetRepository(RepositoryMetadata metadata, EntityManager entityManager) {
Class<?> repositoryInterface = metadata.getRepositoryInterface();
JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
SimpleJpaRepository<?, ?> repo = isQueryDslExecutor(repositoryInterface) ? new QueryDslJpaRepository(
entityInformation, entityManager) : new CustomSimpleJpaRepository(entityInformation, entityManager);
repo.setLockMetadataProvider(lockModePostProcessor.getLockMetadataProvider());
return repo;
}
}
Run Code Online (Sandbox Code Playgroud)
还没有完成,我们还需要你自己的工厂bean在config xml中使用它:
public class CustomRepositoryFactoryBean <T extends JpaRepository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new **CustomJpaRepositoryFactory**(entityManager);
}
Run Code Online (Sandbox Code Playgroud)
}
配置:
<jpa:repositories base-package="bla.bla.dao" factory-class="xxxx.**CustomRepositoryFactoryBean**"/>
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
小智 8
要提供对默认生成的save方法的覆盖,您需要在自己的自定义存储库实现中使用Spring Data存储库实现的聚合.
存储库界面:
public interface UserRepository extends CrudRepository<User, String>{
}
Run Code Online (Sandbox Code Playgroud)
您的存储库实现:
@Repository("customUserRepository")
public class CustomUserRepository implements UserRepository {
@Autowired
@Qualifier("userRepository") // inject Spring implementation here
private UserRepository userRepository;
public User save(User user) {
User user = userRepository.save(entity);
// Your custom code goes here
return user;
}
// Delegate other methods here ...
@Override
public User findOne(String s) {
return userRepository.findOne(s);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的服务中使用您的自定义实现:
@Autowired
@Qualifier("customUserRepository")
private UserRepository userRepository;
Run Code Online (Sandbox Code Playgroud)
为了正确覆盖 save 方法,您必须创建一个接口,该接口具有在 CrudRepository 上声明的原始方法的正确签名,包括泛型
public interface MyCustomRepository<T> {
<S extends T> S save(S entity);
}
Run Code Online (Sandbox Code Playgroud)
然后,创建您的实现(后缀 Impl 在类名中很重要)
public class MyCustomRepositoryImpl implements MyCustomRepository<MyBean> {
@Autowired
private EntityManager entityManager;
@Override
public <S extends MyBean> S save(S entity) {
/**
your custom implementation comes here ...
i think the default one is just
return this.entityManager.persist(entity);
*/
}
}
Run Code Online (Sandbox Code Playgroud)
最后,使用之前创建的界面扩展您的存储库
@RepositoryRestResource
@Repository
public interface MyBeanRepository extends PagingAndSortingRepository<MyBean, Long>, MyCustomRepository<MyBean> {}
Run Code Online (Sandbox Code Playgroud)
我在 OpenJDK 11 上使用 Spring Boot 2.1.4 并且还不断ambiguous reference从编译器收到错误(尽管我的 IDE 使用的 Eclipse JDT 编译器没有问题,所以我没有发现这个问题,直到我尝试构建它在我的 IDE 之外)。
我基本上最终在我的扩展接口中定义了一个具有不同名称的方法,然后default在我的主存储库接口中使用覆盖来在调用正常时调用它save()。
下面是一个例子:
像往常一样定义自定义逻辑的接口:
public interface MyEntityRepositoryCustomSaveAction {
public MyEntity saveSafely(MyEntity entity);
}
Run Code Online (Sandbox Code Playgroud)
使您的存储库扩展该接口:
public interface MyEntityRepository extends JpaRepository<MyEntity, MyEntityId>,
MyEntityRepositoryCustomSaveAction {
@Override
@SuppressWarnings("unchecked")
default MyEntity save(MyEntity entity)
{
return saveSafely(entity);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们已经覆盖了 save() from JpaRepository(嗯,真的CrudRepository是JpaRepository扩展)来调用我们的自定义方法。编译器会警告未经检查的转换,所以如果你想用@SuppressWarnings.
使用自定义逻辑遵循 Impl 类的约定
public class MyEntityRepositoryCustomSaveActionImpl implements
MyEntityRepositoryCustomSaveAction {
@PersistenceContext
private EntityManager entityManager;
@Override
public MyEntity saveSafely(MyEntity entity) {
//whatever custom logic you need
}
}
Run Code Online (Sandbox Code Playgroud)
如果您要重用原始方法,这可能会很有帮助。只需注入EntityManager实现类即可。
public interface MyEntityRepositoryCustom {
<S extends MyEntity> S save(S entity);
}
public class MyEntityRepositoryImpl implements MyEntityRepositoryCustom {
// optionally specify unitName, if there are more than one
@PersistenceContext(unitName = PRIMARY_ENTITY_MANAGER_FACTORY)
private EntityManager entityManager;
/**
* @see org.springframework.data.jpa.repository.support.SimpleJpaRepository
*/
@Transactional
public <S extends MyEntity> S save(S entity) {
// do your logic here
JpaEntityInformation<MyEntity, ?> entityInformation = JpaEntityInformationSupport.getMetadata(MyEntity.class, entityManager);
if (entityInformation.isNew(entity)) {
entityManager.persist(entity);
return entity;
} else {
return entityManager.merge(entity);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您仅使用接口,则可以使用默认方法对CrudRepositoryor进行简单覆盖JpaRepository:
public interface MyCustomRepository extends CrudRepository<T, ID> {
@Override
default <S extends T> S save(S entity)
{
throw new UnsupportedOperationException("writes not allowed");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
40471 次 |
| 最近记录: |