Unable to autowire the Processor after adding User-defined message converters - apache-kafka

On Finchley.SR2, here is the code
#Configuration
#EnableAutoConfiguration
#SpringBootApplication
#EnableBinding(Processor.class)
#RestController
public class Application {
private static Logger log = LoggerFactory.getLogger(Application.class);
#Autowired
private Processor processor;
#Autowired
MappingJackson2MessageConverter testConverter;
#Bean
#StreamMessageConverter
MappingJackson2MessageConverter createTestConverter(){
return new MappingJackson2MessageConverter();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
When I start up, I got
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.stream.messaging.Processor' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
But if I take out #StreamMessageConverter, the Processor can be autowired successfully.
What should I do to keep my customized message converter and autowired Processor at the same time? Thanks!

There is a lot going on there, so lets try to parse it put. . .
First question, why do you need to autowire the following?
#Autowired
private Processor processor;
You, generally don't need to interact with Processor directly since it is used bt the framework to provide a delegation/connectivity model between remote destinations exposed by the binders and your message handlers
Further more, your actual issue is related to a lifecycle which may be a minor yet harmless bug on our end and probably relates to configuring and autowiring Processor in the same configuration class.
Second:
#Configuration
#EnableAutoConfiguration
#SpringBootApplication
You only need one
#SpringBootApplication
Third:
Why do you need to configure MappingJackson2MessageConverter? Content type conversion is a transparent feature of he framework and while we do provide an ability to configure custom message converters, the one you are configuring is already configured by the framework and in fact is the first in the stack of seven pre-configured message converters
The final question:
What is it that your are trying to do? Can you explain your use case?

Related

Spring Boot Geode Unsatisfied dependency expressed through method 'sessionRegion'

The correct dependencies for my gradle.build are driving me crazy!
In order to access an Apache Geode 1.10 server, I am using:
// Geode client dependency
implementation 'org.springframework.geode:spring-geode-starter:1.2.13.RELEASE'
implementation 'org.springframework.data:spring-data-geode:2.2.12.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-tomcat:2.2.13.RELEASE'
This fails with the error:
org.springframework.context.support.AbstractApplicationContext 596 refresh:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'ClusteredSpringSessions' defined in class path resource
[org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
What is there to tell me the dependency missing for the UnsatisfiedDependencyException for 'ClusteredSpringSessions'?
If I remove the #EnableGemFireHttpSession annotation then I get the error
2021-02-02T19:29:49,011 WARN [main] org.springframework.context.support.AbstractApplicationContext 596 refresh:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'cacheManager' defined in class path resource [org/springframework/data/gemfire/cache/config/GemfireCachingConfiguration.class]:
Unsatisfied dependency expressed through method 'cacheManager' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
What is there to tell me the dependency missing for the UnsatisfiedDependencyException for 'cacheManager'?
Thanks
UPDATE The App is run like Spring Boot #ComponentScan finds candidate component class but does not inject #Configuration beans but more specifically
#SpringBootApplication
#ComponentScan({"api", "rsocket", "pricing", "listeners", "dealing", "web"}) // scans packages for # components
#EnableLogging(logLevel="debug", logFile="geodeApi.log")
public class Api {
private static final Logger log = LogManager.getLogger(Api.class);
public static void main(String[] args) {
log.info("In Main");
SpringApplication app = new SpringApplication(Api.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
SpringApplication.run(Api.class, args);
log.info("Out Main");
}
}
The component scan finds various #Component annotated classes for example
#Component
#EnableClusterDefinedRegions(clientRegionShortcut=ClientRegionShortcut.PROXY)
public class ClientCache {
private static final Logger log = LogManager.getLogger(ClientCache.class);
#Resource
private Region<String, String> admin;
#Autowired
LQuote lQuote;
#Autowired
LReject lReject;
#Autowired
LDeal lDeal;
#Autowired
DealNumber dealNumber;
#Autowired
PriceService priceService;
#PreDestroy
public void onDestroy() throws Exception {
log.info("onDestroy");
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
admin.put(guid, "API Shutdown");
// TODO: Cancel all open quote streams
log.traceExit();
}
#Bean
ApplicationRunner StartedUp(){
log.traceEntry("StartedUp");
return args -> {
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
admin.put(guid, "API Started");
lQuote.addListener();
lReject.addListener();
lDeal.addListener();
// Get latest deal number
int currentId = dealNumber.readCurrentId();
// Set it + 1 in case the web server was reboot on the fly
priceService.setCurrentId(currentId + 1);
log.traceExit();
};
}
A lot of the problem was using Java JDK version 15.
The correct versions require Java 11.
// Geode client dependency
implementation 'org.springframework.geode:spring-geode-starter:1.2.8.RELEASE'
implementation 'org.springframework.data:spring-data-geode:2.2.8.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
Technically, it is not necessary to explicitly declare the SDG dependency.
The SBDG dependency (i.e. org.springframework.geode:spring-geode-starter) already includes SDG (org.springframework.data:spring-data-geode). You can follow the dependency trail starting here, then here and finally, here.
As the Version Compatibility Matrix for SBDG specifies, SBDG 1.2.13.RELEASE specifically includes, and is based on, SDG 2.2.12.RELEASE (already), which is (technically) based on Apache Geode 1.9.2.
However, if you need to use Apache Geode 1.10, then you could (recommended) simply declare dependency management to enforce the use of Apache Geode 1.10 in your Gradle build:
plugins {
id 'org.springframework.boot' version '2.2.13.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
dependencyManagement {
dependencies {
dependency 'org.apache.geode:geode-core:1.10.0'
dependency 'org.apache.geode:geode-cq:1.10.0'
dependency 'org.apache.geode:geode-lucene:1.10.0'
dependency 'org.apache.geode:geode-wan:1.10.0'
}
}
dependencies {
implementation 'org.springframework.geode:spring-geode-starter:1.2.13.RELEASE`
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
}
...
WARNING: SDG 2.2.12.RELEASE is officially based on Apache Geode 1.9.2, and though it should work reasonably well with Apache Geode 1.10, there could expectedly be limitations in certain use cases.
This is not unlike what Spring Initializer conveniently generates for you. Of course, Spring Initializer now uses the new SBDG BOM that makes managing individual SBDG module dependencies even easier, which is not unlike how Spring Boot's dependency management manages transitive dependencies, including 3rd party libs.
Regarding the Exceptions...
It really seems to me like you are having configuration problems rather than dependency problems, actually.
Of course, it is hard to say for certain given you shared very minimal Gradle build configuration and no code snippets from your Spring Boot application configuration, only mentions and what I am able to derive from the Exception messages. So, for now, I'll proceed based on what you provided and what I know or could derive.
Looking at this part of the (first) Exception message:
Error creating bean with name 'ClusteredSpringSessions' defined in class path resource
[org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0
And, specifically:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0
This message refers to the (Spring Java) configuration provided by SSDG and imported/auto-configured by SBDG.
The "Unsatisfied dependency", or "parameter 0", is the 1st method parameter in the sessionRegion(..) (Spring JavaConfig-based) #Bean definition method declared in SSDG's configuration. It is the dependency on the GemFire cache instance (e.g. ClientCache) required to create the "ClusteredSpringSessions" Region.
So now, the question becomes, how is the cache created?
Well, this is what the framework is trying to do next... resolve the cache bean dependency (instance reference), which necessary triggers the cache creation first (due to dependency order)...
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError
We see that an IllegalAccessError occurred (O.o) which already smells like a version problem to me, but...
The ClientCacheConfiguration is provided by SDG.
Finally, we arrive at the underlying cause...
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
NOTE: ClientCacheConfiguration extends AbstractCacheConfiguration, which extends AbstractAnnotationConfigSupport, and therefore should have "access" to the protected hasValue(:Number) method.
The main Thread appears to be in one of these Lambdas where the AbstractAnnotationConfig.hasValue(:Number) method is used.
I am no entirely sure what this means...
org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app'
Are you possibly using Spring Boot's new (Layered) Docker Image support by chance?
The 2nd Exception message (involving the cacheManager bean this time) leads to the same outcome, actually. It is no different, but simply involves another bean (i.e. cacheManager bean) with the same dependency on the cache instance:
Error creating bean with name 'cacheManager' defined in class path resource
[org/springframework/data/gemfire/cache/config/GemfireCachingConfiguration.class]
: Unsatisfied dependency expressed through method 'cacheManager' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
And, specifically:
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
tried to access protected method 'boolean org.springframework.data.gemfire
.config.annotation.support.AbstractAnnotationConfigSupport
.hasValue(java.lang.Number)'
And:
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
are in unnamed module of loader 'app')
I am not familiar with this error messages (basically, said class(es) "are in unnamed module of loader 'app'.") What?
How is this Spring Boot app being run?
Definitely providing a sample app, one or more tests, your configuration, logs, Stack Traces in addition to Exception messages, setup, runtime environment, etc, etc, will go along way in trying to understand the context of this problem.
At this point, I am really trying to point you in a direction to start untangling the problem.
Sorry, I cannot (currently) be of more help in this case.

How do I access DispatcherServlet with MockMvc?

I have a basic SpringMVC Application which is running (and mapping) fine.
Now I wanted to set up my UnitTests with MockMvc to perform get requests and stuff.
But if I run the test there is an AssertionError "Status expected: <200> but was: <404>" and my console gives warning "No mapping found for HTTP request with URI [/] in DispatcherServlet with name ''".
I get the feeling my MockMvc cant communicate with my DispatcherServlet, so how do I define this connection?
Here is my short test class:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration
public class HomeControllerTest {
private MockMvc mvc;
#Autowired
private WebApplicationContext wac;
#Before
public void setup() throws ServletException {
mvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
#Test
public void testLandingPagePath() throws Exception {
mvc.perform(get("/")).andExpect(status().isOk());
}
}
So I expected MockMvc to get the location of my DispatcherServlet by default. But it actually doesn't call it for mapping.
I have my "web.xml" and "dispatcher-servlet.xml" located in "WEB-INF" folder and no extra configuration defined.
I got the feeling the problem is based on my project structure, but this is a basic eclipse "Dynamic Web Application", the tests are located in "src/test/java", parallel to "src/main/java".
I appreciate any help, since I spend last 2 hours on reading for solutions but not getting the trick.
After some more time I got things right now:
There is still no way for me to access the dispatcher-servlet.xml in WEB-INF folder. I added a new "config" package to my test-package in parallel to my "controller" test package and put a copy of the dispatcher-servlet.xml in there, called "test-dispatcher-servlet.xml".
Now my test class is able to access this with
#ContextConfiguration("../config/test-dispatcher-servlet.xml")
public class HomeControllerTest {
Hope this can help others who start with spring mvc testing :-)

Unable to create Spring AOP aspect on Spring Data JPA Repository when CGLIB proxies are used

I'm trying to apply an aspect on a Spring Data JPA Repository and it works fine with default Spring AOP config
#EnableAspectJAutoProxy
(when Spring uses standard Java interface-based proxies).
However, when I switch to CGLIB proxies:
#EnableAspectJAutoProxy(proxyTargetClass = true)
I get this exception:
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy59]:
Looks like Spring tries to wrap a CGLIB proxy on a repository class, which is already a CGLIB proxy (generated by Spring Data) and fails.
Any ideas how to make it work?
My Spring Data Repository:
import org.springframework.data.jpa.repository.JpaRepository;
public interface DummyEntityRepository extends JpaRepository<DummyEntity, Integer> {
}
and the aspect:
#Aspect
public class DummyCrudRepositoryAspect {
#After("this(org.springframework.data.repository.CrudRepository)")
public void onCrud(JoinPoint pjp) {
System.out.println("I'm there!");
}
}

Cglib proxy errors using and Spring Data when moving from Spring XD M5 to Release 1.0.0

We're moving a number of batch jobs from Spring XD M5 to the 1.0.0 release.
When creating and deploying the jobs, we are hitting an issue with cglib proxy functionality when autowiring Spring Data repositories (for Neo4J in this case).
The tail end of the stack trace:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'datasetRepository': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class
com.sun.proxy.$Proxy112]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy112
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1512)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 54 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy112]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final
class class com.sun.proxy.$Proxy112
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:494)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:379)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:339)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:421)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1698)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113)
... 61 more
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy112
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
... 68 more
The Spring Data repository interface is annotated with #Repository as follows:
#Repository
public interface DatasetRepository extends GraphRepository<Dataset>
{
public Dataset findOneById(String id);
public Dataset findOneByName(String name);
}
And the corresponding autowired attribute in our bean class which triggers the exception:
#Autowired
private DatasetRepository datasetRepo;
The bean itself is defined in our XD job XML as follows:
<bean id="myBean" class="com.mycompany.MyBean"/>
And the configuration bean (component scanned in the job cfg XML):
#Configuration
#EnableNeo4jRepositories({ "com.mycompany.repositories" })
public class CustomNeo4jConfiguration implements InitializingBean
The versions of Spring Data Neo4J which we deploy into the XD lib folder are as follows:
spring-data-neo4j : 3.2.0.RELEASE
spring-data-neo4j-rest : 3.2.0.RELEASE
The setup is all on a dev PC (for now) with XD running in distributed mode:
redis server
Zookeeper server (1x)
Oracle job repository (local XE instance for now)
1x admin and 1x container
Any help around configuration of the job, Spring Data repository or XD container would be much appreciated.
Thanks
Remove the #Repository annotation on your GraphRepository and you should be fine. Don't forget to enable component scanning.

JTA controlled transactions in JBoss AS7 using EclipseLink, Transaction is required

Environment
Application server: JBoss AS7 (7.1.1 Final)
JPA implementation: EclipseLink (2.4.1)
OS: Windows 7 DB: PostgreSQL 8.4
Update 2, solved
The problem was that i instantiated the AccountService class instead of injecting it using #EJB. After fixing that EntityManager was inected correctly in the service and a transaction was available when doing em.persist(account);
Update
I made a minimal project that shows my problems. Posted to Github:
https://github.com/gotling/jboss-eclipselink-problem
I have two problems that are probably related and due to me not understanding the use of EJB's correct.
I can not get EnityManager to be injected in AccountService.java in persistance JAR, resulting in NullPointerException.
If sending EntityManager in constructor to AccountService no tranasaction is found when doing em.persist.
Project structure
EJB
lib/persistanceunit.jar
web-service.war
Problem
I'm trying to get JBoss to manage transactions in my Java EE service. Problem is that EclipseLink does not seem to pick up the transaction managed by JBoss when trying to persist an entity.
I have followed the guide https://community.jboss.org/wiki/HowToUseEclipseLinkWithAS7 (Alternative 1 and Alternative 2 Step 4) on how to configure JBoss with EclipseLink.
Setup
WAR
Entity manager is injected like this in web-service.war:
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
There is actually a controller class between the class above and the service class, where transformation of the Account object is done, removed it to shorten code.
Persistance Unit
Entity is created like this
AccountService.java in persistanceunit.jar
#Stateless
public class AccountService {
private EntityManager em;
public AccountService(EntityManager em) {
this.em = em;
}
public void create(Account account) {
em.persist(account);
}
}
Stack trace
When calling a WS that should persist the Account entity I get an exception on em.persist(account);
...
Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:692) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:562) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at se.magos.service.AccountService.create(AccountService.java:50) [persistenceunit-0.0.1-SNAPSHOT.jar:]
Questions
I've enabled Trace logging. Should not id.au.ringerc.as7.eclipselinkpersistence be visible in the log?
Is it somehow possible to get the EntityManager injected inside the service class inside the persistanceunit.jar?
In which JBoss / EclipseLink version should this wor out of the box?
You should annotate the bean with #TransactionManagement(TransactionManagementType.CONTAINER) and the create method with #TransactionAttribute(TransactionAttributeType.REQUIRED).
The first annotation is required in order to let the application server know that transactions are managed by the container, the latter to let the method start a transaction, if there is no current one, as soon as it is invoked.
The problem was that AccountService class was instantiated instead of injected using #EJB annotation. After fixing that EntityManager was injected correctly in the service and a transaction was available when doing em.persist(account);
Before
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
After
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
#EJB
AccountService accountService;
public void notify(Notify notify) {
accountService.create(notify);
}
}