JPA #EJB injection does not work and give NullPointerException - java

I've a war file which runs on a wildfly application server.
When I do a SOAP request, a servor log error occurs saying that my EJB session is null. Here's my code :
ColisDAO.java
#Stateless
#LocalBean
public class ColisDao {
public static final String SELECT_ALL_COLIS = "select * from Colis;";
#PersistenceContext(unitName="bdd_colis")
private EntityManager em;
public ColisDao() {
}
public void creer(Colis colis) {
...
}
public void remove(Colis colis) {
...
}
}
RecoveryImpl.java
public class RecoveryImpl {
#EJB
private static ColisDao colisDao;
public static void fillDataBase() throws IOException {
...
some code
...
colisDao.creer(c); //here's my error NullPointer
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="bdd_colis" transaction-type="JTA">
<jta-data-source>java:/bdd_colis</jta-data-source>
<class>data.Colis</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
</properties>
</persistence-unit>
</persistence>
I dont really understand where I've wrong, maybe I have to create ejb file and use InitialContext.lookup() function but I don't really know how to use it in my context.
Any suggestions ?
UPDATE
Finally found the solution :
Here's my new RecoveryImpl class :
RecoveryImpl.java
#EJB(name="ejb/colisDao", beanInterface=ColisDao.class)
public class RecoveryImpl {
public static void fillDataBase() throws IOException {
try {
colisDao = (ColisDao) new InitialContext().lookup("ejb/colisDao");
}
colisDao.creer(c);
}
}

RecoveryImpl class is not a bean, so ColisDao bean won't be injected. Only if class is a bean(specified using annotations like #Stateless #LocalBean), beans get injected.
If class isn't bean and still you want to bean in that class,(hereRecoveryImpl class): Way to access it is using
lookup method of Context

Related

WildFly: No transaction for EntityManager with #Transactional, #Stateless

I am currently facing a weird issue with a plain Java EE application on WildFly 25 for which I don't find the root cause. I've been using similar configurations for a few customers and never had any issue with the code. I know for transactions to work, I need to inject everything involved properly, use the #Stateless annotation and work with the #Transactional annotation on methods which need it. But I never had the issue that I just don't get any transaction, and I am somewhat lost right now. The datasource was also configured with JTA set to true.
My repository:
#Stateless
public class DocumentImportLogRepository{
#PersistenceContext(unitName = "AktenimportPU")
EntityManager em;
public <T> Object find(Class<T> entityClass, Object primaryKey)
{
return em.find(entityClass, primaryKey);
}
public void persist(Object object)
{
em.persist(object);
}
public void forcePersist(Object object)
{
em.persist(object);
em.flush();
}
public void merge(Object object)
{
em.merge(object);
}
public void forceMerge(Object object)
{
em.merge(object);
em.flush();
}
public void remove(Object object)
{
em.remove(object);
}
is called within the following service class:
#Stateless
public class DocumentImportService
[...]
#Inject
DocumentImportLogRepository importLogRepo;
from several methods all originating from:
#Transactional
public void doImport()
{
[...]
readInputFolder(Config.DOCUMENT_IMPORT_FOLDER);
prepareImport(importLogRepo.getByState(State.PARSED), getPersonalakten());
performArchive(importLogRepo.getByState(State.PREPARED));
performArchiveMove(importLogRepo.getByState(State.ARCHIVED));
[...]
}
which is triggered by a controller:
#Named("StartController")
#ApplicationScoped
public class StartController implements Serializable {
#Inject
private transient DocumentImportService importService;
[...]
#Transactional
#TransactionTimeout(value=120, unit = TimeUnit.MINUTES)
public void performTask(Task task)
{
[...]
switch(task)
{
case Personalaktenimport:
importService.doImport();
break;
}
[...]
}
the actual method call failing:
#Transactional
public void readInputFolder(Path inputFolder) throws IOException
{
[...] importLogRepo.forcePersist(entry); [...]
}
with the exception:
javax.ejb.EJBTransactionRolledbackException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context
persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="AktenimportPU">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:jboss/datasources/Aktenimport</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.jdbc.time_zone" value="Europe/Berlin"/>
</properties>
</persistence-unit>
</persistence>
I finally found out what caused this error:
I wasn't really reading the exceptions prior since I thought that they are just commonly caught mistakes in the inputs, but yeah, I had several exceptions caught, however, javax.validation.ValidationException wasn't one of them. The mistake was that the entity had a field BARCODE whose type was an enumeration BARCODE_TYPE which contains a set of predefined values. My intention was to just let it run into an error but continue the import on unknown types, however, if this exception appears it seems to set the transaction into an error state from which the application cannot recover. Removing the #NotNull annotation on the enum field did get rid of the errors.

Stuck converting Spring xml config to java config

I stuck converting my current test app in Spring from using XML configuration to using Java configuration...
I have the following files
App.java
package com.spring.ioc.DependencyInjection;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("app-config.xml");
Phone p = ctx.getBean("phone", Phone.class);
p.calling();
p.data();
}
}
Galaxy.java
package com.spring.ioc.DependencyInjection;
public class Galaxy implements Phone {
public void calling() {
System.out.println("Calling using Galaxy");
}
public void data() {
System.out.println("Browsing internet using Galaxy");
}
}
IPhone.java
package com.spring.ioc.DependencyInjection;
public class IPhone implements Phone {
public void calling() {
System.out.println("Calling using iPhone");
}
public void data() {
System.out.println("Browsing internet using iPhone");
}
}
Phone.java
package com.spring.ioc.DependencyInjection;
public interface Phone {
void calling();
void data();
}
app-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="phone" class="com.spring.ioc.DependencyInjection.IPhone"></bean>
</beans>
The code above allows me to demo how you can use XML & edit the text between 'IPhone' or 'Galaxy' by changing the bean name at the end of the fully qualified name
<bean id="phone" class="com.spring.ioc.DependencyInjection.IPhone"></bean>
or
<bean id="phone" class="com.spring.ioc.DependencyInjection.Galaxy"></bean>
How can do the same in using JavaConfig instead of XML config?
I know how to use Java configuration to just pull one bean but am lost how to set it up to alternate between two objects.
Can you please show me by modifying the code I provided or adding any other code needed?
I believe you can use
#Component("iphone")
public class IPhone {}
#Component("galaxy ")
public class Galaxy {}
and where you inject it,
#Autowired
#Qualifier(value = "iphone")
private Phone iPhone;
#Autowired
#Qualifier(value = "galaxy")
private Phone galaxy;

Setter injection on Interface is taking only the exact name from configurations else throwing exception

I am learning Spring and was trying to implement the following code from the book "Spring in Action". I am not able to understand as to why the Interface property declared with exact name works and else doesn't for a simple Spring application(3.0). Please look into this:
public interface Instrument {
public void play();
}
public interface Performer
{
void perform();
}
public class Saxophone implements Instrument
{
public void play() {
System.out.println("TOOT TOOT TOOT");
}
}
public class Instrumentalist implements Performer
{
private String song;
private Instrument obj; *// not working
// private Instrument instrument; This will work, if replaced* accordingly in the code
public void setSong(String song)
{
this.song=song;
}
public void setInstrument(Instrument instrumen)
{
obj=instrumen;
}
public Instrument getInstrument()
{
return obj;
}
public String getSong()
{
return song;
}
public void perform(){
System.out.println("Playing "+song+" : ");
obj.play();
}
}
The Main class is :
import org.springframework.context.*;
import org.springframework.context.support.*;
class Main
{
public static void main(String ar[])
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("abc.xml");
Performer performer = (Performer) ctx.getBean("kenny");
performer.perform();
}
}
And the configuration are:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-init-method="turnONLights" default-destroy-method="turnOFFLights">
<bean id="kenny" class="Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="obj" ref="saxophone" />
<!-- here also I need to replace obj with "instrument" to make it work -->
</bean>
<bean id="saxophone" class="Saxophone"/>
</beans>
This might be a basic question but yet I am not able to get it.Please help me understand that is it necessary to have the Interface variable have the same name?
Many Thanks
This part looks incorrect...
<property name="obj" ref="saxophone" />
The value of the name attribute needs to be derived from the setter method; in this case, it looks like you want...
<property name="instrument" ref="saxophone" />
Notice that the characters s-e-t are removed, and the first character -- 'i' -- is lower case.

Spring lookup-method and abstract class

Would like to understand how Spring creates a bean from an abstract class, as if it is instantiating an Abstract class, as it is known that is not possible. Would like to know, what is getting instantiated for the "abstractLookupBean" bean.
Thank you.
public abstract class AbstractLookupDemoBean implements DemoBean {
public abstract MyHelper getMyHelper();
public void someOperation() {
getMyHelper().doSomethingHelpful();
}
}
DemoBean class
public interface DemoBean {
public MyHelper getMyHelper();
public void someOperation();
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="helper" class="com.rami.methodlookup.helper.MyHelper" scope="prototype"/>
<bean id="abstractLookupBean" class="com.rami.methodlookup.helper.AbstractLookupDemoBean">
<lookup-method name="getMyHelper" bean="helper"/>
</bean>
<bean id="standardLookupBean" class="com.rami.methodlookup.helper.StandardLookupDemoBean">
<property name="myHelper">
<ref local="helper"/>
</property>
</bean>
</beans>
main class
public static void main(String[] args) {
GenericXmlApplicationContext ctx = null;
try{
ctx = new GenericXmlApplicationContext();
ctx.load("applicationContext.xml");
ctx.refresh();
DemoBean abstractBean = (DemoBean) ctx.getBean("abstractLookupBean"); //What is getting instantiated?
}finally{
ctx.close();
}
Please see spring documentation here
...If the method is abstract, the dynamically-generated subclass will implement the method. Otherwise, the dynamically-generated subclass will override the concrete method defined in the original class...

Spring: Nested application contexts

I have a hierarchy of application contexts. The bean that is defined in the parent context depends on a bean that is defined in the child. Here's how it looks like:
public class X {
public static class A {
public B b;
public void setB(B b) { this.b = b; }
}
public static class B { }
public static void main(String[] args) {
ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext(
"/a.xml");
go1(parent);
}
public static void go1(ClassPathXmlApplicationContext parent) {
GenericApplicationContext child = new GenericApplicationContext(parent);
child.getBeanFactory().registerSingleton("b", new B());
A a = (A) child.getBean("a");
Assert.assertNotNull(a.b);
}
}
The xml file defining the "a" bean looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="a" class="X$A" autowire="byName" lazy-init="true"/>
</beans>
The problem is that B is not injected into A. Injection will occur only if I register the "b" singleton with the parent - which is not an option in my program.
Any ideas?
You can't do that. Parent contexts cannot refer to bean definitions in the child contexts. It only works the other way around.

Categories