Using Vertx with spring-data-neo4j outside Spring container - spring-boot

We have DAO layer which uses Spring data to communicate with Neo4j. Inside DAO layer, it uses the spring annotations #Autowired, #Repository etc. We have API Layer which is written in Vertx. DAO layer is used as a library inside the Vertx application. I am able to use #Inject to inject Models with help of Guice. However, the code block like personDo.findByName('test') fails because it is not able to connect to neo4j outside of spring env. Any suggestions or pointer on how to use spring data without spring application?
DAO layer
// PersonDao.java
#Repository
public interface PersonDao extends CustomerDaoCustom, BaseDao<CustomerDo> {
Optional<PersonDo> findByName(String name);
}
Vertx Application:
import com.example.dao.PersonDao;
import com.example.models.PersonDo;
...
#Inject
private PersonDao personDao;
...
public void findPerson(ServiceRequest request, Handler<AsyncResult<ServiceResponse>> resultHandler) {
String personName = "Sam";
logger.info("Example: finding person with name={}", personName);
Optional<PersonDO> personOpt = personDao.findByName(personName);
personOpt.ifPresentOrElse(person -> {
logger.info("\t Person found: {}", person);
logger.info("\t Person UUID: {}", person.getUuid());
logger.info("\t Details: {}", person.dump());
}, () -> logger.info("\t Person with name={} not found", personName));
personDao is null instead of org.springframework.data.neo4j.repository.query.SimpleQueryByExampleExecutor#379ce046
This can be achieved easily in API if I use the spring boot application to start my vertx service but I am trying not to use Spring boot in my API layer.

Related

Orika mapper spring boot doesn't map when I define a CustomMapper

I have the following structure:
Controller (model classes) -> service -> (domain classes) repository.
This is what I do in the service layer when I have to persist something coming into the request body:
Map the model class (coming from the body request) into the domain class (Trying to use Orika)
Persist the domain class and after getting an OK from the DB
map the domain class saved in the DB into the model class (Trying to use Orika)
return back the response to the controller
This is what I have so far but it's not working:
#Component
public class CustomMapper extends ConfigurableMapper {
private MapperFactory factory = new DefaultMapperFactory.Builder().build();
#Override
protected void configure(MapperFactory factory) {
System.out.println("Spring boot mapper initializing.....");
factory.classMap(ModelSource.class, ModelDestination.class)
.byDefault()
.register();
}
I can see the message "Spring boot mapper initializing....." running spring boot so that means the component is loading OK.
#Autowired
private CustomMapper mapperFacade;
ModelDestination destination = mapperFacade.map(ModelSource.class, ModelDestination.class);
When I check all the destination fields, they are all null. What am I doing wrong? Thanks
Using the last Orika version 1.5.4. This fixed my issue:
.field("chain{}", "chain{}")

Error on injecting service: UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl

I am trying to inject service in spring boot app. However I'm getting following error:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=RecommendationService,parent=RecommendationResourceImpl,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1163111460)
Here is the code:
package com.example.test.recommendations.resources;
#Provider
public class RecommendationResourceImpl implements RecommendationResource {
#Inject
private RecommendationService recommendationService;
#Override
public List<Recommendation> get(String currency,
String entity) {
return recommendationService.getRecommendations(currency, entity));
}
}
Service interface
package com.example.test.recommendations.resources;
// imports
public interface RecommendationService {
List<Recommendation> getRecommendations(String currency, String entity);
Recommendation get(UUID uuid);
}
Service implementation
package com.example.test.recommendations.resources;
//imports
#Component
public class RecommendationServiceImpl implements RecommendationService{
#Override
public List<Recommendation> getRecommendations(String currency, String entity) {
return Collections.emptyList();
}
#Override
public Recommendation get(UUID uuid) {
return null;
}
}
What is correct way to inject services in spring boot applications?
I am using spring boot version 1.3.8 and Jersey version 2.25.1
From your stacktrace it is evident that the server cannot find the dependency bean to be injected.So initially check that the desired bean for the class is getting created during applciation start up.Verify that the service class is in the classpath for component scan to take place, otherwise include the package for scanning.
You are using the #Inject annotation instead of the spring #Autowired annotation to inject the beans.It will work fine but the first and most important difference between #Autowired and #Inject annotation is that the #Inject annotation is only available from Spring 3.0 onwards, so if you want to use annotation-driven dependency injection in Spring 2.5 then you have to use the #Autowired annotation.
Secondly, use the annotation #Service for the service layer rather than using the #Component annotation.
Indicates that an annotated class is a "Service", originally defined
by Domain-Driven Design (Evans, 2003) as "an operation offered as an
interface that stands alone in the model, with no encapsulated state."
May also indicate that a class is a "Business Service Facade" (in the
Core J2EE patterns sense), or something similar. This annotation is a
general-purpose stereotype and individual teams may narrow their
semantics and use as appropriate.
This annotation serves as a specialization of #Component, allowing for
implementation classes to be autodetected through classpath scanning.
#Service
public class RecommendationServiceImpl implements RecommendationService{
#Override
public List<Recommendation> getRecommendations(String currency, String entity) {
return Collections.emptyList();
}
#Override
public Recommendation get(UUID uuid) {
return null;
}
}
I am not an expert on using jersey with springboot , so i do not know if any configurations are causing this issue.
Maybe this thread might be of help to you more:
Dependency injection with Jersey 2.0
You probably never registered your Service with the DI-container. You can do that in your ResourceConfig, which you probably have since you are using jersey:
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(new org.glassfish.hk2.utilities.binding.AbstractBinder() {
#Override
protected void configure() {
bind(RecommendationServiceImpl.class).to(RecommendationService.class).in(Singleton.class);
}
});
packages("com.example.test.recommendations.resources");
}
}
I am using hk2 without spring, so I usually annotate my interfaces with org.jvnet.hk2.annotations.Contract and the implementations with org.jvnet.hk2.annotations.Service. (note: not the spring #Service annotation), so I recommend trying that as well.

Spring Data Rest + ResourceProcessor

I have a ResourceProcessor which shall add a link to a certain PersistentEntityResource (Foo).
The problem is that it kicks in for EVERY PersistentEntityResource in my project which ends in ClassCastExceptions.
When I create a new project with only 2 entities and repositories the processor works fine and only for the Entity which it implements as target.
My question is: What can cause SDR to use this Processor for every PersistentEntityResource and not only for the once for which it is implemented?
#Component
public class FooResourceProcessor implements ResourceProcessor<Resource<Foo>> {
#Override
public Resource<Foo> process(Resource<Foo> resource) {
resource.add(new Link("/foooooooo"));
return resource;
}
I use Spring Boot 1.5.4

Spring Boot, DI possible using interface, but not possible in Spring?

Spring docs says that currently interface DI is not possible. See here: http://www.springbyexample.org/examples/core-concepts-dependency-injection-to-the-rescue.html
I've just started working with Spring boot and I made a simple webapp where I've used DI using interfaces. I can't find the reason on web. Why Spring Boot has this feature while Spring doesn't have!
Please help me in understanding the concept.
Thanks.
Edit
Dao Imple.
#Repository
public class AbcDaoImpl implements AbcDaoInt{
#Autowired
JdbcTemplate jdbc;
#Override
public int selectABC(String user, String password){
// some db query
}
Dao Interface
#Component
public interface AbcDaoInt{
int selectABC(String user, String password);
}
Service
#Service
public class adapter {
#Autowired
AbcDaoInt abcDao;
public Map<String, Object> abc(String user, String password) {
try{
int abcId = abcDao.selectABC(user, pwd);
}
}
There is no difference between spring and spring-boot regarding DI.
It is possible to use an interface for a field and to inject an implementation into that field.
I do not understand what the linked page means by
Interface Injection - This is not implemented in Spring currently
it seems to b wrong our outdated.
what exactly are you gonna do with injecting an interface . isn't interfaces are supposed to be implemented by a java class so whenever you are injecting a interface that means some class implementing the interface should be injected.
this is how you should do it, you have to enable component scan on the package where these classes are present then enable annotaions in order to use annotations.
<context:component-scan base-package="" />
<mvc:annotation-driven>
public interface singleInterface{
void someMethod();
}
#Component(value="b")
class B implements singleInterface{
public void someMethod(){
System.out.println(“from b class”);
}
}
#Component(value=“a”)
class A implements singleInterface{
public void someMethod(){
System.out.println(“from A class”);
}
}
//injecting
#Autowire
#Qualifier("b")
singleInterface bInterface;
bInterface.someMethod();//print from b class.
#Autowire
#Qualifier("a")
singleInterface aInterface;
aInterface.someMethod();//print from a class.
this works on spring boot and on spring mvc you dont have to enable component scan in spring boot.

Which layer is most suitable to handle transaction in Spring 3 Mybatis integrated application?

Currently I develop Spring 3, Mybatis and Struts2 integrated application using MVC architecture.But I face some difficulties to handle transaction in my application.I use Spring Transaction in my service layer,likes this
Service Layer
#Service("MyService")
#Transactional
public class MyServiceImpl implements IMyService {
#Transactional(readOnly=false)
public void myMethod() {
}
}
My question is "Should I use Spring Transaction in my data access layer instead of service layer?" likes this
Data Access Layer
#Repository("MyDAO")
public class MyDAO implements IMyDAO {
#Transactional(readOnly=false)
public void myMethod() {
}
}
If your calling each DAO method through the Service layer than make the service layer transactional. If you call some DAO methods independent of the Service layer than the DAO methods will need to be transactional. You could also make both transactional since Spring will propogate the transactions in both layers, meaning if you call a Service method that is transactional which calls a transactional DAO method, they will share the same transaction.

Resources