I'm developing Jersey-based RESTful Web Services. And, I'm choosing between DeltaSpike Data and Spring Data JPA for my repository layer. I have tried both of them. I'm amazed that they are almost the same.
DeltaSpike Data:
public interface AuthorRepository extends EntityRepository<Author, Long> {
}
Spring Data JPA:
public interface AuthorRepository extends CrudRepository<Author, Long> {
}
But my problem is not as to which one is better and I should choose but, how to apply HK2 dependency injection.
By manually creating AuthorRepository and AuthorRepositoryImpl, I can simply do this configuration:
public class ApplicationBinder extends AbstractBinder {
#Override
protected void configure() {
bind(AuthorRepositoryImpl.class).to(AuthorRepository.class).in(RequestScoped.class);
}
}
But I could not figure out how to apply above similar configuration if I use either DeltaSpike Data or Spring Data JPA since there is not an implementation class for repository interface.
Any help will be appreciated. Thank you.
Personally I would go with Spring Data, as Jersey/HK2 already has an integration module for Spring. This will allow you to inject any Spring beans into your Jersey resources. And the Spring Data repository being a Spring bean, the injection works seamlessly; no need to configure anything with HK2/Jersey. All you would need to configure is the Data configuration for Spring. To get it working, you need to take the following steps:
1) Add the jersey-spring dependency.
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>${jersey2.version}</version>
</dependency>
This will give you the Spring/Jersey integration, allowing you to inject your Spring beans into your Jersey components. See also Combining Spring project and Jersey. It shows some different examples of using both Java configuration an XML configuration.
2) Configure the Spring/Data beans.
This will be your normal configuration, assuming you have done Data configuration with Spring before. This will consist of configuring the JPA vendor, transaction manager, and data source.
3) Inject your repository into your Jersey resource and enjoy.
You can find a complete example in this GitHub Repo
Related
I use custom implementation for Spring Security Plugin to override a default loadUser function. I read this manual https://grails-plugins.github.io/grails-spring-security-core/guide/userDetailsService.html and this is my resources.groovy file:
package spring
import security.ExtendedUserDetails
beans = {
UserDetailsService(ExtendedUserDetails)
}
but it was didn't loaded. App still use a default puligin implementation GormUserDetailsService. I use debugger and I see that ExtendedUserDetails never run.
So what's wrong?
This question is unanswered yet
Custom UserDetailsService Not Being Called - Grails & Spring Security Core
Looks like there is a typo in your bean name in resources.groovy. The name must be userDetailsService not UserDetailsService (capital U) and ExtendedUserDetails must implement GrailsUserDetailsService.
We make a lot of use of spring security core and rest plugins in many apps. So instead of configuring it in each and every app, we decided to create a private plugin to do this functionality by following Burt's blog to convert grails application to plugins.
Specified spring security core and rest in BuidConfig.groovy of private plugin.
We created MyCoreConfig.groovy file and included all spring security core and rest configuration in it, so we can merge this config with Main application config.
The problem is configuration files like BuildConfig.groovy,Config.groovy and resources.groovy(we have customUserDetailsService bean) are excluded while packaging plugin. So we are merging config and resource file in following way
def doWithSpring = {
// TODO Implement runtime spring config (optional)
mergeConfig(application)
userDetailsService(com.organisation.app.CustomUserDetailsService){
grailsApplication = ref('grailsApplication')
}
}
def onConfigChange = { event ->
// TODO Implement code that is executed when the project configuration changes.
// The event is the same as for 'onChange'.
this.mergeConfig(application)
}
private void mergeConfig(GrailsApplication app) {
ConfigObject currentConfig = app.config.grails.myCoreConfig
ConfigSlurper slurper = new ConfigSlurper(Environment.getCurrent().getName());
ConfigObject secondaryConfig = slurper.parse(app.classLoader.loadClass("MyCoreConfig"))
ConfigObject config = new ConfigObject();
config.putAll(secondaryConfig.myCoreConfig.merge(currentConfig))
app.config.grails.myCoreConfig= config;
}
Plugin works fine when all config and resource files are in their respective places.
When we test plugin by commenting configuration from Config.groovy so as to take it from newly created MyCoreConfig.groovy and deleting resources.groovy so as it can take from doWithSpring closure, spring security's core and rest functionality doesn't work.
We even packaged the plugin as jar and included in our main application, and as expected it didn't work either.
So is this approach to extract common functionality in a private plugin which depends on public plugins correct?
Where are we going wrong?
Do people separately configure spring security core or rest in every app or do they follow different methodology to achieve this?
Any pointers in the right direction would be of great help.
Thanks a ton.
I have a web project that has FacesValidator, this validator needs to access an EJB service to verify if a record exists. Unfortunately, I cannot inject my enterprise beans since the validator is not a managed-bean, so I'm trying to access it via InitialContext. I've tried different combination from http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html but failed.
What works is this format:
java:global/myProject-ear-1.0.0/myProject/MyService!com.czetsuya.myProject.service.membership.MyService,
My question is can it be simplify? Seems too long.
Thanks,
czetsuya
Look at the server logs. A bit decent EJB container (at least, Glassfish 3 and JBoss 6/7 do), logs all available JNDI names of the EJB during EJB deployment step. Provided that the validator is properly been put in the WAR and the EJB has a #Local interface, then the shortest JNDI name would be the java:app one which should in your case have been java:app/myProject/MyService.
A completely different alternative is to just make the validator a JSF or CDI managed bean instead, so that you can just use the #EJB annotation.
#ManagedBean // Or #Named.
#ApplicationScoped // Provided that the instance doesn't have any state.
public class MyValidator implements Validator {
#EJB
private MyService myService;
// ...
}
and reference it by binding instead of validatorId:
<f:validator binding="#{myValidator}" />
Note that from JSF 2.2 on, you should be able to inject #EJB in a #FacesValidator (and #FacesConverter).
See also:
How to inject in #FacesValidator with #EJB, #PersistenceContext, #Inject, #Autowired
Spring Webflow: 2.3.1
Spring Data: 1.0.2
JSF: 2.1.9
Primefaces: 3.3.1
I'm trying to combine Spring Data JPA Repositories with JSF DataModel, in this case, Primefaces with LazyDataModel. This happens in a WebApp integrating Spring with JSF, using Spring Webflow.
The problem is when i use a JpaRepository inside LazyDataModel that lives in ViewScope of Spring Webflow:
Could not serialize flow execution; make sure all objects stored in
flow or flash scope are serializable
org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.(SerializedFlowExecutionSnapshot.java:75)"
Without the JpaRepository inside LazyDataModel, i cannot get the correct page and use the Pagination model of spring data. I already found someone with the same problem, but unfortunately no one answered:
http://forum.springsource.org/showthread.php?116022-Webflow-Serialization-error-on-object-holding-ref-to-JPA-Data-Repository
Thanks for you help in advance
Best regards
JSimas
Already found a solution for this problem!
Whenever you need to add a reference to a Spring Data JPA Repository in an object that will live in your spring webflow context, just to declare the JPA repository as transient! Then you need to add the following annotations in the object that contain the transient reference:
#Configurable - to mark the class to be configured on the fly (this will add some overhead to your application, be careful to use this annotation only when you need)
#Autowired - add this to the transient JPA Repository
So, if you're extending a DataModel JSF base class, and you want to add some JPA repository, here is an example:
#Configurable
public class XptoLazyDataModel extends LazyDataModel<Xpto> {
#Autowired
private transient JpaRepository<Xpto> repository;
(...)
}
And there you go. Hope that this can help someone.
Best regards
It also occurred to me that I should apply the transient keyword to my JPA repository field, as you have. This solved the problem, however, I did not need to use #Configurable or #Autowired.
public class Servlet2Stateless extends HttpServlet {
#EJB private HelloUserLocal helloUser;
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println(newSess.getName());
}
will above line of code work when I have EJB and Servlet deployed on different servers? or I need to call it through traditional way????
If the EJB resides on the different server than your client (Servlet) than you cannot use the dependency injection with #EJB annotation.
I guess that you'll need to go with the old JNDI way.
According to EJB 3.1 spec, you can use #EJB annotation in a variety of clients, including servlets which is your case.
The problem is that you are running client and server in different hosts. Depending on the server you are using, you might be able to use the EJB annotation. This post explains how to do it in Weblogic.
Needless to say you have to define the server EJB as #Remote in either case.
If your container also supports CDI, you could write a CDI producer method for the bean whcih does the JNDI lookup. Then you can at least separate the lookup from the injection site.
What about using dependency injection in a standalone client ?