I'm migrating an application from GlassFish 3.1 to JBoss 6.1.
This code worked wonderfully with GlassFish, but throws an ugly error with JBoss:
Custom annotation:
#Named
#ViewAccessScoped
#Stereotype
#Target( { ElementType.TYPE, ElementType.METHOD, ElementType.FIELD } )
#Retention(RetentionPolicy.RUNTIME)
public #interface Model {
}
Bean:
#Model
public class MyBean extends BaseBean {
#Inject
UserService userService
public void save() {
startTransaction();
studioService.persist(studio);
commitTransaction();
}
}
Base Bean:
public class BaseBean implements Serializable {
#Resource
protected UserTransaction transaction;
#PersistenceContext(unitName = "fits_PU")
protected EntityManager entityManager;
[...]
protected void startTransaction() {
try {
transaction.begin();
entityManager.joinTransaction();
} catch [a few exceptions]
}
protected void commitTransaction() {
try {
transaction.commit();
} catch [an awful lot of exceptions]
}
}
I get the following exception:
Caused by: java.lang.IllegalArgumentException: Can not set javax.transaction.UserTransaction field my.company.project.BaseBean.transaction to org.jboss.tm.usertx.client.ServerVMClientUserTransaction
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) [:1.7.0_11]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) [:1.7.0_11]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) [:1.7.0_11]
at java.lang.reflect.Field.set(Field.java:680) [:1.7.0_11]
I've been Googling for it the whole afternoon, but couldn't find any hint to start with. Any idea?
So. I looked around, tried and error'd, and saw I was wrong.
I don't need to manage any UserTransaction if I'm using EJB, since the transaction is managed by the the container. Hence,
I removed every reference to it in my Beans
I changed my #Named Services into #Stateless EJB
I injected them into my Beans with the #EJB annotation instead of #Inject
Hope it will help someone else.
Related
i am searching for a way to create a listener that is also a spring component, however when i try to autowire the entity manager bean, it is always null, what am i doing wrong?
#Component
public class TestListener {
#Autowired
private TestRepository entityManager;
#PrePersist
#PreUpdate
void beforeEntityUpdateOrSave(final Entity entity) {
entityManager.someOperation() // -> NullPointerException, because the bean is "null"
}
}
the Entity class has the listener in the #EntityListeners annotation.
#EntityListeners(TestListener.class)
public class Entity
Is the class TestRepository annotated with #Repository?
You could try making the field entityManager final. I would also recomend using constructor injection instead. Field injection sometimes leads to strange behaviour.
#Component
public class TestListener {
private final TestRepository entityManager;
public TestListener(#Autowired TestRepository entityManager){
this.entityManager = entityManager;
}
...
}
}
#Stateless
public class MyAccountsBean {
#Inject SomeEntityClass someOtherBean;
#Resource UserTransaction jtaTx;
#PersistenceContext(unitName="AccountsPU") EntityManager em;
#Resource QueueConnectionFactory accountsJMSfactory;
#Resource Queue accountPaymentDestinationQueue;
public List<Account> processAccounts(DepartmentId id) {
// Use all of above instance variables with no additional setup.
// They automatically partake in a (server coordinated) JTA transaction
}
}
There are likely multiple issues, but one that sticks out is that all of the fields should be marked with the private modifier.
In addition, can you post the rest of your codebase and the error you are getting?
I'm using Axon 4.3 with JPA/Spring.
I want to inject entityManager in my interceptor, so i used ContainerManagedEntityManagerProvider in my configuration. but i have this error when i run my application
Description: Parameter 0 of method configureCommandBus in AxonConfig
required a bean of type
'org.axonframework.springboot.util.jpa.ContainerManagedEntityManagerProvider'
that could not be found.
Action: Consider defining a bean of type
'org.axonframework.springboot.util.jpa.ContainerManagedEntityManagerProvider'
in your configuration.
#Configuration
#AutoConfigureAfter(AxonAutoConfiguration.class)
public class AxonConfig {
#Bean
public CommandBus configureCommandBus(org.axonframework.springboot.util.jpa.ContainerManagedEntityManagerProvider containerManagedEntityManagerProvider) {
CommandBus commandBus = SimpleCommandBus.builder().build();
commandBus.registerDispatchInterceptor(
new CatalogDispatchInterceptor(containerManagedEntityManagerProvider.getEntityManager()));
return commandBus;
}
}
public class CatalogDispatchInterceptor implements MessageDispatchInterceptor<CommandMessage<?>> {
private final EntityManager entityManager;
public CatalogDispatchInterceptor(EntityManager entityManager) {
this.entityManager = entityManager;
}
#Override
public BiFunction<Integer, CommandMessage<?>, CommandMessage<?>> handle(
List<? extends CommandMessage<?>> messages) {
return (index, command) -> {
(CreateCatalogCommand.class.isInstance(command.getPayloadType())) { }
return command;
};
}
}
The ContainerManagedEntityManagerProvider instance created by Axon, if you are using the Spring Boot Starter, through the JpaAutoConfiguration looks as follows:
#Bean
#ConditionalOnMissingBean
public EntityManagerProvider entityManagerProvider() {
return new ContainerManagedEntityManagerProvider();
}
Hence my first try would be to wire in a EntityManagerProvider instead of the ContainerManagedEntityManagerProvider. If that doesn't work, then you're dealing with a Spring bean ordering issue, which is somewhat out of the (axon) framework's scope I think. You could always just create the ContainerManagedEntityManagerProvider yourself of course, which i am pretty certain of will solve the problem at hand.
Hope either solution helps you out Aymen!
I'd like for my ResourceConfig to have access to a database for its configuration. I've tried this:
#ApplicationPath("/api")
public class ApplicationConfig extends ResourceConfig {
#PersistenceContext(unitName = "myPU")
private EntityManager em;
#Inject
private MyEjb myEjb;
#PostConstruct
public void init() {
// em and myEjb are both null
...
}
But neither the EntityManager, not the EJB, are injected (both are null)
Is there a special way to do this in JAX-RS?
NOTE: I'm able to inject resources into a Path-annotated class just fine. I'm having trouble doing it in the actual ApplicationPath-annotated class.
We have set up the Spring Framework like this:
#Eager
public interface CatalogElementRepository extends PagingAndSortingRepository<CatalogElementEntity, Long> {
}
#Service
public class CatalogImpl implements CatalogManager {
#Inject
CatalogElementRepository catalogElementRepository;
#Override
public CatalogElement createCatalogElement(CatalogElementEntity catalogElement) {
return this.catalogElementRepository.save(catalogElement);
}
}
#Stateless
#Remote(CatalogManager.class)
public class CatalogManagerBean implements CatalogManager {
#Inject
CatalogManager delegate;
#Override
public CatalogElement createCatalogElement(CatalogElementEntity catalogElement) {
return this.delegate.createCatalogElement(catalogElement);
}
}
So whenever someone calls the method on the remote interface createCatalogElement, I'd assume the entity gets stored in the database. It does not (weirdly enough, findOne still returns the very same entity, but it can't be found via findByProperty).
Other questions said to add #Transactional, so I added #javax.transaction.Transactional and org.springframework.transaction.annotation.Transactional on the methods and classes to be on the safe side, nothing worked.
What could be the problem?
I don't see any configuration files for the Spring Framework, but it's a legacy project, so they might just be hidden very well.
For some reason using this class as a producer for the EntityManager helped:
public class SpringConfig {
#PersistenceUnit
EntityManagerFactory emf;
#PersistenceContext
EntityManager em;
#Produces
#ApplicationScoped
public EntityManagerFactory createEntityManagerFactory() {
return this.emf;
}
#Produces
public EntityManager createEntityManager() {
return this.em;
}
public void close(#Disposes EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
public void close(#Disposes EntityManager entityManager) {
entityManager.close();
}
}