Is PersistenceContext allowed in RequestScoped bean? - ejb

With following class,
#Path("/somes")
#RequestScoped
public class SomesResource {
#PersistenceContext(unitName = "some")
private EntityManager entityManager;
#Inject
private SomeService someService;
}
Where,
#Stateless
public class SomeService {
#PersistenceContext(unitName = "some")
private EntityManager entityManager;
}
Question 1: Is it O.K. to be injected with #PersistenceContext in #RequestScoped bean?
Question 2: Is entityManager in SomesResource need to be worked with an UserTransaction in any modification job?
Question 3: Are two entityManagers effectively same instance?

Related

#Value not visible inside #component filter during tests

I created filter which logging and saving all requests, this is part of this:
#Component
public class RequestFilter extends OncePerRequestFilter {
#Value("${app.endpoint}")
private String requestMapping;
private final RequestRepository requestRepository;
#Autowired
public RequestFilter(RequestRepository requestRepository) {
this.requestRepository = requestRepository;
}
....
}
When app is running requestMapping is properly readed from spring context, but
when I created test for that filter requestMapping is null
#SpringBootTest
#RunWith(SpringRunner.class)
#AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
#ContextConfiguration(classes = {MyApplication.class})
#AutoConfigureMockMvc
#ActiveProfiles("test")
public class FilterTest {
#Autowired
private WebApplicationContext webApplicationContext;
#Autowired
private RequestRepository requestRepository;
#Autowired
protected MockMvc mockMvc;
#Before
public void setup() {
RequestFilter rpmRequestFilter = new RequestFilter(this.requestRepository);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(invalidVpmRequestFilter)
.build();
}
}
And of course in application-test.properties I have configured this property:
app.endpoint=/log/save
Does someone know where the problem can be? Why this is doesnt work in tests?
As M. Deinum pointed out, the problem is that you are creating an instance of RequestFilter and if you want Spring to inject components (#Autowired) or propoerties (#Value) in it, you have to let Spring handle the instantiation as follow :
#....
public class FilterTest {
....
#Autowired
RequestFilter requestFilter;
#Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(requestFilter)
.build();
}
}

Java batch - inject ejb to batchlet

I have a startup bean. I want to start some batchlet job in this.
I annotated the batchlet class by use #Nemed and #Dependent . I want to use some ejb like ReportService in batchlet but Injection not work. How can I inject EJB to my batchlet?
I deployed below example on wildfly 11.0.0.Alpha1 and got empty reference in service object.
BatchletTest:
#Dependent
#Named("BatchletTest")
public class BatchletTest extends AbstractBatchlet{
public BatchletTest() {
}
#Inject
ReportService service;
#Override
public String process() throws Exception {
System.out.println(service);
return null;
}
}
test-job.xml
<job id="test-job" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="testStep">
<batchlet ref="com.test.BatchletTest" />
</step>
</job>
StartupBean:
#Singleton
#Startup
#TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class StartupBean {
private Logger logger = LoggerFactory.getLogger(StartupBean.class);
#PostConstruct
private void startup() throws Exception {
long executionId = BatchRuntime.getJobOperator().start("test-job", new Properties());
System.out.println("myJob started, execution ID = " + executionId);
}
}
ReportService:
#Stateless
public class ReportService {
.....
}
You are no implementing any interface with #Local anntotaion on your class ReportService.
Try this:
#Stateless
#LocalBean
public class ReportService {
.....
}
or
#Stateless
public class ReportService implements ReportServiceLocal{
.....
}
#Local
public interface ReportServiceLocal {
.....
}
Please check this link

Mockito and EJB

Good evening everybody,
I have a EJB class. This class has 2 attributes are EJB, with private access, and "injected" with EJB annotation #EJB. This class has no defined constructor.
I want to test this class by using Mockito.
I have 2 problems :
1) the 2 attributes are with private access
2) Even when i want to put a defined constructor with the 2 EJB attributes as parameters, it does not work in my TestNG class
In my TestNG class,
i only want instantiate my class of course,
and also her 2 EJB attributes as 2 mocks.
And i do not succeed.
Thank you very much,
Thomas
This is the class.
package fr.nomenclature.service;
#Stateless
#Local
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class TraitementNomenclaturesImpl implements TraitementNomenclatures {
private static final Logger LOG = LoggerFactory.getLogger(TarificationFactureImpl.class);
#EJB(name = "AccesNomenclatures-interne-ebx")
private transient AccesNomenclatureEBX accesEbx;
#EJB(name = "AccesElementFacturation-interne-ebx")
private transient AccesElementFacturationEBX accesRefEbx;
/*
* (non-Javadoc)
*
* #see
* fr.atom.referentiel.sante.nomenclature.service.TraitementNomenclature#extraireNomenclaturesDesPrestations(java
* .util.List, java.util.Date, fr.atom.configuration.SoapContext)
*/
#Override
public ContenusNomenclatures extraireNomenclaturesDesPrestations(
final List<PrestationDeSante<? extends Identifiant>> pPrestations, final Date pDateTraitement,
final SoapContext pContext) {
.......
}
}

autowiring selective beans into a list reference

I have a service interface I with implementaions I1,I2,I3...I10 out of which I want to use I1-I5 to be autowired as a List<I> in controller class C. The I6-I10 should not be be autowired. How can I achieve this. Moreover the I implementations are annotated #Service beans. I do not want to move them to xml declarations.
Based on the comment by mvb13 I have tried to weave a solution for the problem....
So I write a class extending ArrayList and mark it a Component
#Component("mysublist")
public class MyList extends ArrayList implements ApplicationContextAware
{
#Value("comma.sep.eligible.beans.classnames")
private String eligibles;
private ApplicationContext appCtx;
#PostConstruct
public void init()
{
Map allBeans = appCtx.getBeansOfType(I.class);
for(Object bean:allBeans.values())
{
if(eligibles.contains(bean.getClass().getSimpleName()))
{
add(bean);
}
}
}
public void setApplicationContext(ApplicationContext appCtx)
{
this.appCtx = appCtx;
}
}
Now I can autowire the above bean in my required class definition as:
#Service
public class MyService
{
#Resource(name="mysublist")
private List<I> myReqdBeans;
......
}
*Please ignore the generics related implications in the code.
You should use #Qualifier. It defines any subset that you need.
#Autowired
#Qualifier("MySubset")
private List<I> list;
But I think you should move your bean definitions in xml to use <qualifier ... /> property. I think you haven't another option to specify qualifier.
The #Qualifier annotation should give you what you need. You need to apply it in two places:
On the #Service beans that you wish to include in the sub-list
On the #Autowired list injected into your controller
So addressing the #Service beans first:
#Service
#Qualifier("MySubList")
public class MyService implements IMyService
{
}
And then within your Controller:
#Controller
public class MyController
{
#Qualifier("MySubList")
#AutoWired
private List<IMyService> myServices;
}
This instructs Spring to #AutoWire all IMyService implementations #Qualified as "MySubList"

Produce an Entitymanager with extended persistence context via CDI

We are trying to build a system, which "produces" an entitymanager depending on the logged-in user (kind of multitenancy). Therefor we implemented a stateless ejb like this:
#Stateless
#TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class CustomEntityManagerFactory {
#PersistenceContext(unitName = "EM1")
private EntityManager em1;
#PersistenceContext(unitName = "EM2")
private EntityManager em2;
#Produces
#RequestScoped
public EntityManager getEntityManager() {
// check which entitymanager to return
}
}
The entitymanager is injected like this:
#Stateless
public class EmployeeService {
#Inject
private EntityManager em;
...
}
This producer works as long as only an entitymanager without extended persistence context is needed (in stateless ejb). Unfortunately we also have some stateful ejbs, which need the extended persistence context. Is there a way to implement a CDI producer for this purpose or does this approach only work for stateless ejb with transactional entitymanager?
My guess is you need this:
Create two factories here:
#ApplicationScoped
public class EntityManagerFactoryProducer {
private static EntityManagerFactory factory;
private static EntityManagerFactory factory2;
#Produces
public EntityManagerFactory getEntityManagerFactory(InjectionPoint ip) {
// if the field is named exactly factory2 then factory2 is produced
if (ip.getMember().getName().equals("factory2")) {
if (factory2 == null) {
factory2 = Persistence.createEntityManagerFactory("EM2");
}
return factory2;
}
else {
if (factory == null) {
factory = Persistence.createEntityManagerFactory("EM1");
}
return factory;
}
}
Use factories to createEntityManagers
public class EntityManagerProducer {
#Inject
private EntityManagerFactory factory;
#Inject
private EntityManagerFactory factory2;
#Produces
#RequestScoped
public EntityManager getEntityManager() {
return factory.createEntityManager();
}
#Produces
#RequestScoped
#MyCustomQualifier
public EntityManager getEntityManager2() {
return factory2.createEntityManager();
}
}
The qualifier used to differ between entitymanagers
#Qualifier
#Retention(RUNTIME)
#Target({FIELD })
public #interface MyCustomQualifier {
#Nonbinding
public String value() default "";
}
end usage:
#Inject
EntityManager em;
#Inject
#MyCustomQualifier
EntityManager em2;
Of course you can use the qualifier to differ between factories instead of checking the name of the field. I just wanted to get some more depth into the answer.

Resources