Partially implemented repository with Spring data Neo4j 4 - java

I'm trying to partially implement a repository using the following structure:
public interface ExampleCustomRepository {
Iterable<Example> findExamplesByUserId(Long id);
}
#Repository
#Transactional
public class ExampleCustomRepositoryImpl implements ExampleCustomRepository {
#Autowired
private Neo4jTemplate template;
#Override
public Iterable<Example> findExamplesByUserId(final Long id) {
// implementation
}
}
public interface ExampleRepository extends GraphRepository<Example>, ExampleCustomRepository {
}
For some reason the RepositoryFactory wants to create a DerivedGraphRepositoryQuery for this implemented method, and fails:
org.springframework.data.mapping.PropertyReferenceException: No property userId found for type Example!
Is it even possible to partially implement a repository with SDN4? If it is, what am I doing wrong?

I overlooked the naming convention, which was explained here.
I had too rename ExampleCustomRepositoryImpl to ExampleRepositoryImpl.

Related

Error when trying to make generic method in spring boot app

This is my code Service interface (which i am trying to generify):
#org.springframework.stereotype.Service
public interface Service<T extends Planning> {
List<T> get(Specification<T> spec, Sort sort);
//PagingResponse getOther(Specification<T> spec, HttpHeaders headers, Sort sort);
}
And I created another class that extends to Service class, here are my PlanningServiceImpl class :
#Data
#Service
public class PlanningServiceImpl implements PlanningService, com.qoze.meeting.services.Service<Planning> {
#Autowired
private PlanningRepositoryInterface planningRepository;
#Override
public Iterable<Planning> getAllPlannings() {
return planningRepository.findAll();
}
#Override
public List<Planning> get(Specification<Planning> spec, Sort sort){
return planningRepository.findAll(spec, sort);
}
}
My PlanningService interface :
public interface PlanningService{
Iterable<Planning> getAllPlannings();
}
First the compiler doesn't recognize the spec parameter given in parameter. Then I change to put the extends on T object.
But here with my service I only allowed to work with Planning objects, I wanted at the beginning to have a generic Service and use several objects. Can someone help to have a generic service in spring boot app?

How to implement custom method of CrudRepository in Spring boot 2.0?

I can find this question has been asked earlier. But neither the answer nor the documentation is working for me. I follow this doc.
I would like to add 2 custom interface to the repository. I must be doing something wrong in my code.
The compiler gives error:
Error:(18, 8) java: com.ma.home.service.BuyerPartyDetailsServiceImpl is not abstract and does not override abstract method deleteAll() in org.springframework.data.repository.CrudRepository.
Custom repository:
#Repository
public interface CustomBuyerPartyDeatilsDAO {
#Query("SELECT b FROM BuyerPartyDetails buyer WHERE LOWER(buyer.xmlFileName) = fileName")
public List<BuyerPartyDetails> listByfileName(String fileName);
#Query("SELECT b FROM BuyerPartyDetails buyer WHERE LOWER(buyer.buyerOrganisationName) = name")
public BuyerPartyDetails getByBuyerPartyByName(String name);
}
Repository:
#Repository
public interface BuyerPartyDetailsDAO2 extends
CrudRepository<BuyerPartyDetails, Long>, CustomBuyerPartyDeatilsDAO {
public List<BuyerPartyDetails> listByfileName(String fileName);
public BuyerPartyDetails getByBuyerPartyByName(String name);
}
Service:
#Service
public class BuyerPartyDetailsServiceImpl implements
BuyerPartyDetailsDAO2,
CustomBuyerPartyDeatilsDAO {
#Autowired
private BuyerPartyDetailsDAO2 buyerPartyDetailsDAO2;
public BuyerPartyDetailsServiceImpl() {
}
// more implementation removed.
.......
.......
}
If I provide the implementation for deleteAll(), it asks one by one all the CrudRepository methods such as save(), saveAll(), findById(), findAll(), etc.
So how can use CrudRepository already implemented methods?
To resolve this error
com.ma.home.service.BuyerPartyDetailsServiceImpl is not abstract and does not override abstract method deleteAll() in org.springframework.data.repository.CrudRepository
you have to override all abstract methods and provide implementation for them to make it functional.
If you don't need to implement them all then you have to inject DAO interfaces into services and let the services implement their own interfaces.
Spring will do the rest by providing suitable implementation of your interfaces that you should configure in the application context.

How to force Spring Data to create query methods with entity runtime type?

I've got around 5 objects that I want to do similar things with.
I figured out that not to polute the code I will put a logic for those objects in one place.
public class MetaObjectController<T extends MetaObject> {
#Autowired
private final MetaObjectRepository<T> repository;
// generic logic
Here's how repository looks:
public interface MetaObjectRepository<T extends MetaObject> extends GraphRepository<T> {
T findByName(String name);
}
Now, I create concrete class which uses delegation:
public class ExperimentalController {
#Autowired
private final MetaObjectController<MetaCategory> metaController;
#RequestMapping(method = RequestMethod.POST)
public void add(#RequestBody MetaCategory toAdd) {
metaController.add(toAdd);
}
Now, when I look at the generated queries I see, that although instantiated correctly, repository puts MetaObject as an entity name instead of runtime type.
Is there a way to force the repository to use runtime type?
Please don't advise to put a #Query annnotation. That's not what I am looking for.
This is most probably due to type erasure: at runtime there is only the type constraint available which is MetaObject. If you want to use (via spring-data) the actually relevant subclass you will have to create explicit interfaces of the MetaObjectRepository like this:
public class Transmogrifier extends MetaObject
public interface MetaTransmogrifierRepository
extends MetaObjectRepository<Transmogrifier> {}

Java - Spring data access object implementation

In my current spring setup i would like to implement a slightly different architecture, here is my setup:
I have a "base" DAO interface, which lists all CRUD operations:
public interface BaseDao {
public boolean create(Object obj);
public List<Object> read();
public boolean update(Object obj);
public boolean delete(Object obj);
}
Next i have "specific" DAO interface, which extends from the "base" one:
public interface ArticleDao extends BaseDao {
public List<Article> getArticlesByAttribute(String attribute);
}
And finally, the Repository, which implements the interface:
public class ArticleDaoImpl implements ArticleDao {
public boolean create(Article article) {
// code
}
public List<Article> read() {
// code
}
public boolean update(Article article) {
// code
}
public boolean delete(Article article) {
// code
}
public List<Article> getArticlesByAttribute(String attribute) {
// code
}
}
So the idea is simple:
I want every Repository to implement all crud operations + "the methods from the specific dao-interface"
But i get the following error:
ArticleDaoImpl is not abstract and does not override
abstract method delete(java.lang.Object) in BaseDao
etc..
So this is probably because i defined Object as a parameter in the interface and "Article" as a parameter in the actual implementation..
Anybody got the idea how i can follow this pattern correctly?
Should i consider working with generics?
Thanks and Greetings
No. You should work with Spring Data JPA/MongoDB etc. It will make MOST of your boilerplate code go away. Seriously - forget about DAO and go with Spring Data JPA: https://spring.io/guides/gs/accessing-data-jpa/

Manual setup of Spring Data JPA repositories, with custom implementation

I am trying to manually define custom spring data repository, I have following 3 classes :
public interface PersonRepository extends JpaRepository<Person, Long>...
public interface PersonRepositoryCustom
public class PersonRepositoryImpl implements PersonRepositoryCustom {
#Resource
private PersonRepository personRepository;
......
}
To configure this in a Configuration class I have the following:
#Bean
public PersonRepositoryImpl personRepositoryImpl() {
return new PersonRepositoryImpl();
}
#Bean
public PersonRepository personRepository() {
return getFactoryBean(PersonRepository.class, personRepositoryImpl());
}
private <T> T getFactoryBean(Class<T> repository, Object customImplementation) {
BaseRepositoryFactoryBean factory = new BaseRepositoryFactoryBean();
factory.setEntityManager(entityManager);
factory.setBeanFactory(beanFactory);
factory.setRepositoryInterface(repository);
if (customImplementation != null) {
factory.setCustomImplementation(customImplementation);
}
factory.afterPropertiesSet();
return (T) factory.getObject();
}
The problem I am having is that I am getting
"Error creating bean with name 'personRepository': Requested bean is currently in creation: Is there an unresolvable circular reference"
This seems to be due to the fact that the PersonRepositoryImpl contains a resource reference to the personRepository interface.
If I use the EnableJpaRepositories on the config class then everything seems to work fine.
However I don't want to use that annotation, it scans based on packages, and I want more fine grained configurability.
So does anyone know how to manually setup a spring custom repository, that allows injection without the circular reference problem?
Anyone?
You can create a CustomRepository interface extending Repository<T,ID extends Serializable>. Then you can implement CustomRepositoryImpl by yourself if you want full control of your repositories. You can refer to SimpleJpaRepository as implementation example.

Categories

Resources