Spring Data Mongo Repository:: Common shared method across all Repo issue - mongodb

Use Case
I am trying to use Adding custom behaviour to all repositories functionality of Spring Data MongoDB.
The documentation unhelpfully describes how to connect using JPA. Anyways got the config setup with Mongo equivalent.
I want to add a findByCategoryName(String categoryName) method to all entities as all my entities will have a Category . Category is a DBRef object so have to use custom query.
Below is relevant part of the config
<!-- Activate Spring Data MongoDB repository support -->
<mongo:repositories base-package="com.domain.*.repo" repository-impl-postfix="CustomImpl"
factory-class="com.domain.commonrepo.CommonMongoRepoFactoryBean"/>
<bean id="mappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<mongo:mapping-converter mapping-context-ref="mappingContext">
<mongo:custom-converters base-package="com.domain.mongo.converter" />
</mongo:mapping-converter>
<bean id="entityInformationCreator" class="org.springframework.data.mongodb.repository.support.DefaultEntityInformationCreator">
<constructor-arg name="mappingContext" ref="mappingContext" />
</bean>
.
.
The FactoryBean
#NoRepositoryBean
public class CommonMongoRepoFactoryBean<T extends MongoRepository<?,?>, ID extends
Serializable> extends MongoRepositoryFactoryBean{
#Autowired
private static MongoTemplate mongoTemplate;
protected MongoRepositoryFactory getRepositoryFactory(Class<T> clazz) {
return new CommonMongoRepoFactory(clazz);
}
private static class CommonMongoRepoFactory extends MongoRepositoryFactory {
private Class clazz;
public CommonMongoRepoFactory(Class clazz) {
super(mongoTemplate);
this.clazz = clazz;
}
public CommonMongoRepoImpl getTargetRepository() {
return new CommonMongoRepoImpl(clazz);
}
public Class<?> getRepositoryClass() {
return CommonMongoRepoImpl.class;
}
}
I know it's a bit of a hack but with no documentation it is a pain. If anyone knows better PLEASE give me a github link :-)
Common Repo interface
#NoRepositoryBean
public interface CommonMongoRepo<T, ID extends Serializable> extends MongoRepository<T,ID> {
public List<T> findByCategoryName(String categoryName);
Implementation
#NoRepositoryBean
public class CommonMongoRepoImpl<T, ID extends Serializable> extends SimpleMongoRepository<T,
ID> implements CommonMongoRepo<T, ID> {
private Class<T> type;
#Autowired
private static MongoTemplate mongoOperations;
#Autowired
private static EntityInformationCreator entityInformationCreator;
#Autowired
private CategoryRepo categoryRepo;
public CommonMongoRepoImpl(Class<T> type) {
super((MongoEntityInformation<T, ID>) entityInformationCreator.getEntityInformation(type), mongoOperations);
}
#Override
public List<T> findByCategoryName(String categoryName) {
Category category = categoryRepo.findByName(categoryName);
return mongoOperations.find(query(where("categories.$id").is(category.getId())), type);
}
PROBLEM
Now when I am trying to use the common method I get an exception
No Property category found in "Entity". Which is I guess when mongo repo is trying to auto implement the method. This is inspite of me declaring the bean as #NoRepositoryBean
PLEASE HELP!!! Dont want to add the same custom method to all the entities

Here is the best solution!
Step One:
Add a custom method to interface!
增加一个自定义的方法
#custom interface
/**
* Basic Repository for common custom methods
* #author liangping
*/
import java.io.Serializable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
#NoRepositoryBean
public interface WootideRepositoryCustom <T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID>, MongoRepository<T, ID> {
public Page<T> search(Query query, Pageable pageable);
}
Implementation
Step Two:
Add implement for your custom method!
实现你的自定义方法
/**
* implement for wootide basic repository
* #author liangping
*/
import java.io.Serializable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
public class WootideRepositoryImpl<T, ID extends Serializable> extends
SimpleMongoRepository<T, ID> implements WootideRepositoryCustom<T, ID> {
public WootideRepositoryImpl(MongoEntityInformation<T, ID> metadata,
MongoOperations mongoOperations) {
super(metadata, mongoOperations);
}
#Override
public Page<T> search(Query query, Pageable pageable) {
long total = this.getMongoOperations().count(query, this.getEntityInformation().getJavaType() );
return new PageImpl<T>(this.getMongoOperations().find(query.with(pageable), this.getEntityInformation().getJavaType()), pageable, total);
}
}
Create a new factory for custom repository
/**
* Repository Factory for all Subrepository
* #author liangping
*/
import java.io.Serializable;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.MappingMongoEntityInformation;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
public class WootideRepositoryFactoryBean<R extends MongoRepository<T, I>, T, I extends Serializable>
extends MongoRepositoryFactoryBean<R, T, I> {
#Override
protected RepositoryFactorySupport getFactoryInstance(
MongoOperations operations) {
return new WootideMongoRepositoryFactory<T,I>( operations );
}
private static class WootideMongoRepositoryFactory<T, ID extends Serializable>
extends MongoRepositoryFactory {
private MongoOperations mongo;
public WootideMongoRepositoryFactory(MongoOperations mongoOperations) {
super(mongoOperations);
this.mongo = mongoOperations;
}
#SuppressWarnings("unchecked")
protected Object getTargetRepository(RepositoryMetadata metadata) {
TypeInformation<T> information = ClassTypeInformation.from((Class<T>)metadata.getDomainType());
MongoPersistentEntity<T> pe = new BasicMongoPersistentEntity<T>(information);
MongoEntityInformation<T,ID> mongometa = new MappingMongoEntityInformation<T, ID>(pe);
return new WootideRepositoryImpl<T, ID>( mongometa, mongo);
}
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return WootideRepositoryCustom.class;
}
}
}
Make it works
<mongo:repositories base-package="com.***.mongodb"
factory-class="com.***.mongodb.custom.WootideRepositoryFactoryBean"/>
Good Luck! 祝你好运!

Somewhat delayed but here is sample code that does this for a Spring web app project. The salient points are:
Interface used in Controller
Implementation done in a separate class that inherits from a base
The base implementation provides common methods that any other Controller can use with just a quick inheritance

Related

How to specify collection name while using spring data mongo repository?

I am using spring data to fetch data for my application.
The repository class uses a mongo entity class which is being added as an upstream dependency to my project which means I don't have any control to change the source code of the class. As a result of this, I cannot use #Document annotation from org.springframework.data.mongodb.core.mapping to my mongo entity class.
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface DummyRepository extends MongoRepository<Dummy, String> {
Page<Dummy> findAll(Pageable pageable);
}
Here, I don't have any control over source code of Dummy class so I can't add #Document to specify collection name for this class
How can I specify the collection name while using DummyRepository to query mongo collection?
One way would be to use #EnableMongoRepositories#repositoryFactoryBeanClass with your own flavor of MongoRepsoitoryFactoryBean overriding getEntityInformation(Class).
Unfortunately there's a bug (DATAMONGO-2297) in the code and for the time being you also need to customize getTargetRepsoitory(RepositoryInformation) as shown in the snippet below.
#Configuration
#EnableMongoRepositories(repositoryFactoryBeanClass = CustomRepoFactory.class)
class config extends AbstractMongoConfiguration {
// ...
}
class CustomRepoFactory extends MongoRepositoryFactoryBean {
public CustomRepoFactory(Class repositoryInterface) {
super(repositoryInterface);
}
#Override
protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
return new MongoRepositoryFactory(operations) {
#Override
public <T, ID> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
return new MappingMongoEntityInformation(
operations.getConverter().getMappingContext().getPersistentEntity(domainClass)) {
#Override
public String getCollectionName() {
return "customize-as-you-wish";
}
};
}
#Override // you should not need this when DATAMONGO-2297 is resolved
protected Object getTargetRepository(RepositoryInformation information) {
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
return getTargetRepositoryViaReflection(information, entityInformation, operations);
}
};
}
}

Why #Autowired not working all the time?

Im trying to setup mongodb with SpringBoot and im not using context.xml but trying to configure with configuration class and annotations.
package com.configuration;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
#Configuration
#EnableMongoRepositories(basePackages = "com.mongo")
public class MongoConfig extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
return "mongodbname";
}
#Override
public Mongo mongo() throws Exception {
return new MongoClient("127.0.0.1", 27017);
}
#Override
protected String getMappingBasePackage() {
return "com.mongo";
}
}
My repository looks like this :
package com.mongo.repositories;
import com.mongo.documents.Sequence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository("sequenceRepository")
public class SequenceRepository{
#Autowired
private MongoTemplate mongoTemplate;
public Sequence findOne(Query query){
return this.mongoTemplate.findOne(query,Sequence.class);
}
public List<Sequence> find(Query query){
return this.mongoTemplate.find(query,Sequence.class);
}
public void save(Sequence object){
this.mongoTemplate.save(object);
}
public void delete(Sequence object){
this.mongoTemplate.remove(object);
}
}
If i use like this in the rest controller it is working properly :
package com.controllers;
import com.mongo.documents.Sequence;
import com.mongo.repositories.SequenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class IndexController {
#Autowired
private SequenceRepository sequenceRepository;
#RequestMapping("/")
public String index(){
Sequence sequence = new Sequence();
sequence.setClassName("class.Test");
sequence.setActual(1);
sequenceRepository.save(sequence);
return "index";
}
}
But if i want to use the SequenceRepository inside the Sequence document like this :
package com.mongo.documents;
import com.mongo.repositories.SequenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document
public class Sequence {
#Autowired
private SequenceRepository sequenceRepository;
#Id
private String id;
private String className;
private int actual;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public int getActual() {
return actual;
}
public void setActual(int actual) {
this.actual = actual;
}
public void save(){
this.sequenceRepository.save(this);
}
public void delete(){
this.sequenceRepository.delete(this);
}
}
After that I change the code in the controller to :
package com.controllers;
import com.mongo.documents.Sequence;
import com.mongo.repositories.SequenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class IndexController {
#Autowired
private SequenceRepository sequenceRepository;
#RequestMapping("/")
public String index(){
Sequence sequence = new Sequence();
sequence.setClassName("class.Test");
sequence.setActual(1);
sequence.save();
return "index";
}
}
I got a nullPointerExceeption at this point in the save() method.
There is no need to inject your Repository inside your Domain object Sequence as it is really bad design to have a dependency between the domain objects and your repository classes.
To follow some good practices, your Service classes or if you don't need a Service layer, your Controller classes should inject your Repository beans.
In your last code snippet your are already doing it, but the .save() method should be called on your repository SequenceRepository and not on the domain object Sequence.
An example could be the following:
#RestController
public class IndexController {
#Autowired
private SequenceRepository sequenceRepository;
#RequestMapping("/")
public String index(){
Sequence sequence = new Sequence();
sequence.setClassName("class.Test");
sequence.setActual(1);
// now let's save it
sequenceRepository.save(sequence);
return "index";
}
}
You can only autowire Spring-managed components into other Spring-managed components. Your sequence object is not a component (not annotated with #Component, #Service, #Repository or #Controller etc.)
I suggest you follow rieckpil's advice.

Injection of #PersistenceContext in CDI-Unit

Here is the unit testing code. When we run unit test code (SampleServiceTest2); EntityManager injected in AbstractDao is always null! How can we inject em during unit test.
*** SampleServiceTest2.java
import javax.inject.Inject;
import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(CdiRunner.class)
public class SampleServiceTest2 {
#Inject SampleService greeter;
#Test
public void testGreeter() throws Exception {
System.out.println("before2");
greeter.addSampleData(new SampleDataDto(), new KullaniciDto());
System.out.println("after2");
}
}
*** SampleService.java
import javax.ejb.Stateless;
import javax.inject.Inject;
....
#Stateless
#SecuredBean
public class SampleService {
#Inject
SampleLogic sampleLogic;
#Yetki(tag="perm_add_sample_data")
public void addSampleData(SampleDataDto data, KullaniciDto aktifKullaniciDto){
SampleDataHelper sampleDataHelper = new SampleDataHelper();
SampleData sampleData = sampleDataHelper.getEntity(data);
KullaniciHelper kullaniciHelper = new KullaniciHelper();
Kullanici kullanici = kullaniciHelper.getEntity(aktifKullaniciDto);
sampleLogic.addData(sampleData, kullanici);
}
}
**** SampleLogic.java
import javax.inject.Inject;
....
public class SampleLogic {
#Inject
SampleDataDao sampleDataDao;
public void addData(SampleData data, Kullanici kullanici) {
addData1(data,kullanici);
System.out.println("SampleLogic : addData() called!");
}
public void addData1(SampleData data, Kullanici kullanici) {
sampleDataDao.create(data, kullanici);
}
}
**** SampleDataDao.java
public class SampleDataDao extends AbstractDao<SampleData> {
private static final long serialVersionUID = 1L;
}
**** AbstractDao.java
public abstract class AbstractDao<T extends BaseEntity> implements Serializable {
private static final long serialVersionUID = 1L;
#PersistenceContext(unitName="meopdb")
private EntityManager em;
protected EntityManager getEm() {
return em;
}
#SuppressWarnings("rawtypes")
private Class entityClass;
#SuppressWarnings("rawtypes")
private Class getEntityClass() {
if (entityClass == null) {
entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
return entityClass;
}
public T create(T t, Kullanici kullanici) {
if (t.getId() != null) {
throw new IllegalStateException("Create Operation: Oid should be null");
}
t.setId(getSeqNextValue(t));
t.setEklemeZamani(new Timestamp(Calendar.getInstance().getTimeInMillis()));
t.setEkleyenKullaniciId(kullanici.getId());
t.setDurumId(EnumDurum.AKTIF.getValue());
t = em.merge(t);
em.flush();
return t;
}
}
If you test with CDIUnit, the only thing you get is CDI injections, not the full power of Java EE. Injecting entityManager using #PersistenceContext into AbstractDAO is not part of standalone CDI, it is only supported when application is running within a Java EE application server.
The solution is to inject EntityManager using CDI mechanism and create a producer. The producer could be then switched for an alternative in unit tests to provide test entityManager. However, setting up JPA in a standalone unit test is not so straightforward, as you need to specify connection properties directly in persistence.xml file. Also, do not forget to add dependencies on a JPA implementation (hibernate, eclipselink) into your test dependencies.
However, if you do not want to adapt your application's code or you need more than CDI in your tests, you should have a look at Arquillian Java EE test framework.
Here is an example for CDIUnit:
public abstract class AbstractDao<T extends BaseEntity> implements Serializable {
...
#Inject
#Named("meopdb")
private EntityManager em;
...
}
// producer in application - just a wraper over `#PersisteneContext`
public class EntityManagerProducer {
#Produces
#PersistenceContext(unitName="meopdb")
#Named("meopdb")
private EntityManager em;
}
/* producer in your test sources - it creates entityManager via API calls instead of injecting via `#PersistenceContext`. Also, a different persistence unit is used so that it does not clash with main persistence unit, which requires datasource from app server
*/
public TestEntityManagerProducer {
#Produces
#ProducesAlternative // CDIUnit annotation to turn this on as an alternative automatically
#Named("meopdb")
public EntityManager getEm() {
return Persistence
.createEntityManagerFactory("meopdb-test")
.createEntityManager();
}
}
And it is not yet enough. You need to create a new persistence.xml in your test resources with the test persistence unit named "meopdb-test". For this unit you need to specify RESOURCE_LOCAL transaction-type, and specify connection information. And last thing not to forget - you need to list all your entities in the persistence.xml, or in external orm file. This is because your tests run outside of application server. Inside app server, JPA can find entities automatically.
As #OndroMih said, in CDI-Unit, the only thing you get is CDI injections. So you have to cheat a little.
You can use extension do add javax.inject.Inject annnotation to all #PersistenceContext injections
import java.util.Set;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.*;
import javax.inject.Inject;
import javax.persistence.PersistenceContext;
import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider;
import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder;
public class AddInjectToPersistenceContextInjectionsCdiExtension implements Extension {
<T> void processAnnotatedType(#Observes ProcessAnnotatedType<T> pat) {
Set<AnnotatedField<? super T>> fields = pat.getAnnotatedType().getFields();
for (AnnotatedField<? super T> field : fields) {
if (shouldInjectionAnnotationBeAddedToField(field)) {
AnnotatedType<T> at = pat.getAnnotatedType();
AnnotatedTypeBuilder<T> builder = new AnnotatedTypeBuilder<T>().readFromType(at);
Inject injectAnnotation = AnnotationInstanceProvider.of(Inject.class);
builder.addToField(field, injectAnnotation);
pat.setAnnotatedType(builder.create());
}
}
}
private <X> boolean shouldInjectionAnnotationBeAddedToField(AnnotatedField<? super X> field) {
return !field.isAnnotationPresent(Inject.class) &&
field.isAnnotationPresent(PersistenceContext.class);
}
}
and produce suitable EntityManager in test class
#RunWith(CdiRunner.class)
#AdditionalClasses(AddInjectToPersistenceContextInjectionsCdiExtension.class)
public class SampleServiceTest2 {
#Inject SampleService greeter;
EntityManagerFactory emf;
#PostConstruct
void init() {
emf = Persistence.createEntityManagerFactory("integration");
}
#Produces
EntityManager createEntityManager() {
return emf.createEntityManager();
}
#Test
public void testGreeter() throws Exception {
}
}
It's not exactly equivalent of what Java EE container does, but it's close enough more often than not.

Exclude null properties from save operation

I'm using Spring Data for MongoDB -1.4.1.RELEASE and MongoDB 2.4.9
I'm using the mongoOperations.save() in order to update entities.
On previouse version, 1.2.0.RELEASE (due to a bug: DATAMONGO-571 ) I used to exclude some of the properties by setting their value to be null.
Now, This bug was fixed, and I'm not able to do so, but I still need to exclude some properties from the save operation (in case of update).
Does someone have an idea how this can be achieved?
I wrote abstract repository, that do partial update for single object. It expect that object contain 'id' field.
package xxx;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
import java.io.Serializable;
import java.util.Map;
public abstract class ExtendedMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> {
private Class<T> clazz;
//hidden constructor
private ExtendedMongoRepository(MongoEntityInformation metadata, MongoOperations mongoOperations) {
super(metadata, mongoOperations);
}
public ExtendedMongoRepository(MongoRepositoryFactory mongoRepositoryFactory, MongoOperations mongoOperations, Class<T> clazz) {
this(mongoRepositoryFactory.<T, ID>getEntityInformation(clazz), mongoOperations);
this.clazz = clazz;
}
protected Query getByIdQuery(ID id) {
return new Query(Criteria.where("_id").is(id));
}
/**
* Partial object update
* #param entity
* #param id
* #return
*/
public T updatePartial(T entity, ID id) {
ObjectMapper objectMapper = new ObjectMapper();
//exclude null
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
Map<String, Object> objectAsMap = objectMapper.convertValue(entity, Map.class);
//exclude id
objectAsMap.remove("id");
//add fields to update
Update u = new Update();
for (Map.Entry<String, Object> e : objectAsMap.entrySet()) {
u.set(e.getKey(), e.getValue());
}
getMongoOperations().updateFirst(getByIdQuery(id), u, clazz);
return getMongoOperations().findById(id, clazz);
}
}
And example how to use it.
public class GroupRepository extends ExtendedMongoRepository<Group, String> {
#Autowired
public GroupRepository(MongoRepositoryFactory mongoRepositoryFactory, MongoOperations mongoOperations) {
super(mongoRepositoryFactory, mongoOperations, Group.class);
}
}
MongoTemplate has dedicated methods to perform partial updates like:
updateFirst(…) - updates the first document matching a given criteria.
updateMulti(…) - updates all documents matching a given criteria.

External #EJB injection return null with RESTeasy and JBoss

I'm developing a RESTful Web Service on JBoss 6 Final with RESTeasy.
I have an external EJB and I want inject EJB on Web Service.
This is the code of EJB
BeanLocalInterface.java
#Local
public interface BeanLocalInterface {
public String sayHello();
}
Bean.java
#Stateless
#LocalBinding(jndiBinding = "BeanLocal")
public class Bean implements BeanLocalInterface {
#Override
public String sayHello() {
return "Hello!";
}
}
In another project I have a WS:
#Path("/ws")
public class HelloWorldResource {
#EJB(mappedName="BeanLocal")
private BeanLocalInterface bean;
#GET
#Path("/hello")
#Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
return bean.sayHello();
}
}
MyRESTApplication.java
public class MyRESTApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
private Set<Class<?>> empty = new HashSet<Class<?>>();
public MyRESTApplication(){
singletons.add(new HelloWorldResource());
}
#Override
public Set<Class<?>> getClasses() {
return empty;
}
#Override
public Set<Object> getSingletons() {
return singletons;
}
}
bean is alwasy null!
I have tried this solution:
I have put #Stateless on HelloWorldResources
I have create beans.xml in WEB-INF
I have change MyRESTApplication with
#ApplicationPath("wsapp")
public class MyRESTApplication extends Application {
}
Can you help me?
PS: I don't have EAR e I don't want use it
I have managed to solve this. Firstly, remove all settings from web.xml regarding RESTeasy. You only need one adnotation --> #ApplicationPath
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("api")
public class MyRESTApplication extends Application {
//nothing required here, leave this empty
}
This is your session bean interface.
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("MyEJB")
public interface BeanInterface {
#Path("{username}")
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayHello(#PathParam("username") String username);
}
This is your session bean.
import javax.ejb.Stateless;
#Stateless
public class EJB implements BeanInterface{
#Override
public String sayHello(String username) {
return "Hello, "+username;
}
}
With JBOSS 7.1
Usage: http:// localhost:8080 /YOURAPPNAME/api/MyEJB/Fabio
Output:Hello, Fabio
Hope this helps.