I am using Mybatis 3.3.0 and EJB 3.1 running in a Wildfly 8.2.1 App server.
I modified my EJB's to have a Remote Interface and Injected the interface into all my classes that require the functionality instead of the injecting the LocalBean implementation (as it was before).
This caused all my useGeneratedKeys configurations for my mapper file Insert statements to stop working. Now my ID fields remain Null after the Inserts have run successfullly.
How is it that this caused mybatis to not be able to populate the ID's into my POJOs.
It turns out that mybatis gets confused when your EJB's are proxied and it isn't able to put the generated ID back into the POJO.
To fix it you simply have to inject the EJB Annotated with #javax.ejb.LocalBeanimplementation directly into the class you want to use it in. This is instead of injecting the Interface annotated with #javax.ejb.Remote.
Additionally I tested the same implementation using Remote EJB's and found you still won't be able to get generated Keys back from mybatis if you inject the #javax.ejb.Remote Interface type. I haven't found a solution to getting the generated ID into the POJO when using remoting.
I have a EntityListener that needs to be configurable (typical data source info: driver, user, password), but I´d like to avoid adding one more properties file to the project. Is there any way to retrieve from some standard configuration place such as web.xml? It seems that injection via #Resource will be only available in JPA 2.1 (I am using JPA 2.0).
UPDATE - to make this clear
In my entity bean, I have an annotation #EntityListeners(MyEntityListener.class). So MyEntityListener may have methods annotated with #PostPersist for example. When my entity bean is gonna be persisted, this method is called. What I want is to retrieve the data for MyEntityListener initialization without using another configuration file.
http://openjpa.apache.org/builds/2.2.1/apidocs/org/apache/openjpa/audit/Auditor.html does the trick. It works (my bad, it was a misconfiguration of mine). Actually it works pretty well.
<property name="openjpa.Auditor" value="com.acme.Auditor(param2=10,param2='hello')"/>
I made a simple app with the following dependency tree for components:
Service1 injects Service2(via constructor)
Service2 injects SomeContext(via setter)
SomContext injects Service1(via setter)
Advisor is for Service1
So when spring tries to construct Service1 or Service2 it automatically tries to apply advise, but there is a check in spring - isCurrentlyInCreation (in BeanFactoryAdvisorRetrievalHelper.java), so the bean for which it tries to apply advise is still it creation and skips advise applying.
I know that recurse of bean is a bad way of design but it is hard to decouple now and refactor.
I fix this issue with the help of factorybean for SomeContext and loading of Service1 when needed via applicationcontext(applicationcontextaware), but maybe someone knows better solution?
You can workaround this if you apply compile time weaving instead of load time weaving. Here are two posts that can get you started:
Spring, Aspects, #Configurable and Compile Time Weaving using maven
Spring #Transactional: Verifying transaction support / Local method calls
I have a maven client project that i run as maven test. First thing i do in the junit test is a lookup using the jndi string. Here i receive a stateless bean proxy which is cast to a remote interface. As soon as i call a method from the interface (like saving some domain objects wich uses a data access object wich uses jpa) i receive the exception
javax.ejb.NoSuchEJBException: No such EJB[appname=,modulename=someName,distinctname=,beanname=SomeBean]
The documentation says: "A NoSuchEJBException is thrown if an attempt is made to invoke a business method on a stateful session or singleton object that no longer exists". The thing is that the bean is stateless and not stateful or a singleton. I'm also quite sure that the jndi string is correct, because if i make the same lookup and persistence-method-call in the main method of the client project (run as maven build with "install jboss-as:deploy") everything works fine.
Any suggestions how i could use the persistence methods from the proxy when testing? Some colleagues have a similar setup and it works for them without Arquillian or so.
I don't know why but it works now. What I did was removing the getter-method for the EntityManager within the abstract generic DaoBean that all DaoBeans inherit. Having the getter was suddenly shown as an Error while executing the client (it wasn't shown as error before).
I'm currently migrating a JBoss service class from AS5.1 to AS6 (not going to AS7 for a variety of reasons).
For AS5.1, the service implements a {serviceName}MBean and has a jboss-service.xml with attribute values. It's packaged in a jboss-sar, which is packaged in an EAR to be deployed. When deployed, the service fields are populated with the values from jboss-service.xml, and the service is automatically registered into JMX.
I would like to achieve the same thing using AS6, but would like the service to support CDI - so I'd like its new #Inject injection points to be satisfied. I need these to be satisfied in the object registered with JMX, so that methods called via JMX can reference injected fields, but I'm struggling to achieve this.
I've had to package the service in a jar, instead of a jboss-sar, for classloader reasons, but let's say it's otherwise unchanged. When deployed to AS6, all works as before - service goes into JMX, values from XML propagate to the object. However, the instance created does not have its CDI injection points satisfied, and neither does the object registered in JMX.
If I annotate the service class with #Startup and #javax.ejb.Singleton, but keep its interface and the jboss-service.xml, the object registered into JMX still does not have its CDI injection points satisfied. However if I programmattically deregister that bean, and re-register the instance in a #PostConstruct method, then the bean in JMX DOES have its injection points satisfied. However that bean no longer has the values specified in the jboss-service.xml.
So how can I get the best of both worlds? CDI and the usual JBoss service behaviour? What is the correct way to implement a JBoss service with CDI? I've been unable to find documentation on this. Hope someone can help.
Thanks,
Ben
As a worst-case fallback, you should be able to use the CDI extension API to get your service to be injected. I don't think you would need to write a fully-fledged extension, but if you have an initialisation hook in the service object, you can do this (lifted with minor editing from the docs, not compiled or tested):
public static <T> void inject(T object) {
BeanManager beanManager = (BeanManager)new InitialContext().lookup("java:comp/BeanManager");
AnnotatedType<T> type = beanManager.createAnnotatedType(object.getClass());
InjectionTarget<T> it = beanManager.createInjectionTarget(type);
CreationalContext ctx = beanManager.createCreationalContext(null);
it.inject(object, ctx);
it.postConstruct(object);
}
Basically, any object to that method will get injected. All the usual CDI annotations should work. Hopefully.
As mentioned in the comments above, it seems Tom's right - there's no 'nice' way of created a CDIed, JMX bean in one go, you either have to put your JMX bean in CDI, as is suggested above, or put you CDIed bean into JMX. We tried the former, but it appears the BeanManager isn't bound to JNDI at the point the service starts up.
So instead we went with CDI bean -> JMX. We're creating the services as Singleton EJBs, so their injection points are satisfied, and they then get registered/unregistered to JMX in their PostConstruct/PreDestroy methods, using German Escobar's excellent CDI portable extension (germanescobar.net/2010/01/cdi-portable-extension-jmx.html, community.jboss.org/thread/148750 is also helpful).
May try to use ApplicationScoped beans and get them to start by observing a ContainerInitialized(?) event, however, as we don't need all the features of an EJB. Haven't tried that yet, mind...