Datos de Spring: anula el método save

Estoy considerando datos de spring para un proyecto. ¿Es posible anular el método de guardado generado por defecto? Y si es así, ¿cómo?

Simplemente cree su interfaz personalizada de la forma habitual y declare allí los métodos que desea modificar con la misma firma que la expuesta por CrudRepository (o JpaRepository , etc.). Supongamos que tiene una entidad MyEntity y un repository MyEntityRepository y desea anular el método de MyEntityRepository de MyEntityRepository que toma una única instancia de entidad, luego defina:

 public interface MyEntityRepositoryCustom {  S save(S entity); } 

e implemente este método como desee en su MyEntityRepositoryImpl , como de costumbre:

 @Transactional public class MyEntityRepositoryImpl implements MyEntityRepositoryCustom { public  S save(S entity) { // your implementation } } 

Y luego, como siempre, deja que MyEntityRepository implemente MyEntityRepositoryCustom .

Al hacer esto, Spring Data JPA llamará al método save de su MyEntityRepositoryImpl lugar de la implementación predeterminada. Al menos esto funciona para mí con el método de delete en Spring Data JPA 1.7.2.

Supongo que extiendes SimpleJpaRepository:

 public class **CustomSimpleJpaRepository** extends SimpleJpaRepository { @Transactional public  S save(S entity) { //do what you want instead } } 

A continuación, asegúrese de que se utiliza en lugar del SimpleJpaRepository predeterminado ampliando:

 public class CustomJpaRepositoryFactory extends JpaRepositoryFactory { protected  JpaRepository getTargetRepository(RepositoryMetadata metadata, EntityManager entityManager) { Class repositoryInterface = metadata.getRepositoryInterface(); JpaEntityInformation entityInformation = getEntityInformation(metadata.getDomainType()); SimpleJpaRepository repo = isQueryDslExecutor(repositoryInterface) ? new QueryDslJpaRepository( entityInformation, entityManager) : new CustomSimpleJpaRepository(entityInformation, entityManager); repo.setLockMetadataProvider(lockModePostProcessor.getLockMetadataProvider()); return repo; } } 

Todavía no hecho, también necesitamos tener su propio grano de fábrica para usarlo en el config xml:

 public class CustomRepositoryFactoryBean , S, ID extends Serializable> extends JpaRepositoryFactoryBean { protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { return new **CustomJpaRepositoryFactory**(entityManager); } 

}

la configuración:

  

Espero eso ayude.

Para proporcionar la anulación del método de guardado generado por defecto, debe usar la agregación de la implementación del repository de Spring Data dentro de su propia implementación de repository personalizado.

Interfaz de repository:

 public interface UserRepository extends CrudRepository{ } 

Su implementación de repository

 @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); } } 

Luego use su implementación personalizada en su servicio:

 @Autowired @Qualifier("customUserRepository") private UserRepository userRepository; 

No conseguí que esto funcionara bien, así que puse mi lógica requerida en una clase de servicio y dejé intactos los métodos de guardar los repositorys.

Utilice escuchas de eventos JPA como @PrePersist, @PreUpdate. Esto funcionará si el proveedor JPA subyacente es compatible con estas características. Esta es la función JPA 2, por lo que la última Hibernate, EclipseLink, etc. debe ser compatible.

Esto podría ser útil si va a reutilizar el método original. Simplemente inyecte EntityManager en la clase de implementación.

 public interface MyEntityRepositoryCustom {  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 save(S entity) { // do your logic here JpaEntityInformation entityInformation = JpaEntityInformationSupport.getMetadata(MyEntity.class, entityManager); if (entityInformation.isNew(entity)) { entityManager.persist(entity); return entity; } else { return entityManager.merge(entity); } } }