I'm using 2 PU in stateless EJB and each of them is invoked on one method:
#PersistenceContext(unitName="PU")
private EntityManager em;
#PersistenceContext(unitName="PU2")
private EntityManager em2;
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW )
public void getCandidates(final Integer eventId) throws ControllerException {
ElectionEvent electionEvent = em.find(ElectionEvent.class, eventId);
...
Person person = getPerson(candidate.getLogin());
...
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW )
private Person getPerson(String login) throws ControllerException {
Person person = em2.find(Person.class, login);
return person;
}
Those methods are annotated with REQUIRES_NEW transcaction to avoid this exception. When I was calling these method from javaFX applet, all worked as expected. Now I'm trying to call them from JAX-RS webservice (I don't see any logical difference as in both cases ejb was looked up in initial context) and I keep getting this exception. When I set up XADatasource in glassfish 2.1 connection pools, I got nullpointer exception on em2.
Any ideas what to try next?
Regards
Ok,
it's solved now. I'll share just in case somebody got tackled by similar thing.
Whole problem was with netbeans deploying. They overwrite the settings in glassfish connection pool and when you set them proper at runtime, you got npe's or missing password silly stuff. The place to edit this is sun-resources.xml. XML element has attributes datasource-classname and rs-type. What needs to be done in case of Derby database is:
<jdbc-connection-pool ...
datasource-classname="org.apache.derby.jdbc.ClientXADataSource"
res-type="javax.sql.XADataSource">
...
</jdbc-connection-pool>
Works like a charm now.
I'm using 2 PU in stateless EJB and each of them is invoked on one method
Indeed. But you're calling the second method from the first one so you're doing a distributed transaction and you need to use XA for this (at least for one of the resource since GlassFish supports the last agent optimization allowing to involve one non-XA resource). In other words, setting one of your datasource as a XADataSource is the way to go.
If you get an error when doing this, please add details about what you did exactly and the stacktrace.
When calling the second method from the first, it is not an EJB method call. It treats it as just a regular method call and does not look at #TransactionAttribute. If you want a call to the same EJB, you can inject the SessionContext and call getBusinessObject. Then call the method on the returned EJB.
Related
I am having trouble finding information about this issue I am running into. I am interested in implementing row level security on my Postgres db and I am looking for a way to be able to set postgres session variables automatically through some form of an interceptor. Now, I know that with hibernate you are able to do row-level-security using #Filter and #FilterDef, however I would like to additionally set policies on my DB.
A very simple way of doing this would be to execute the SQL statement SET variable=value prior to every query, though I have not been able to find any information on this.
This is being used on a spring-boot application and every request is expected to will have access to a request-specific value of the variable.
Since your application uses spring, you could try accomplishing this in one of a few ways:
Spring AOP
In this approach, you write an advice that you ask spring to apply to specific methods. If your methods use the #Transactional annotation, you could have the advice be applied to those immediately after the transaction has started.
Extended TransactionManager Implementation
Lets assume your transaction is using JpaTransactionManager.
public class SecurityPolicyInjectingJpaTransactionManager extends JpaTransactionManager {
#Autowired
private EntityManager entityManager;
// constructors
#Override
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
super.prepareSynchronization(status, definition);
if (status.isNewTransaction()) {
// Use entityManager to execute your database policy param/values
// I would suggest you also register an after-completion callback synchronization
// This after-completion would clear all the policy param/values
// regardless of whether the transaction succeeded or failed
// since this happens just before it gets returned to the connection pool
}
}
}
Now simply configure your JPA environment to use your custom JpaTransactionManager class.
There are likely others, but these are the two that come to mind that I've explored.
I know that injection using the #EJB annotation is only possible in an EJB class, a servlet, or a JSF managed bean, but in the same time I need to have an instance of a some injected business interface in a POJO class, so I thought of doing the following:
in my JSF managed bean
#EJB BusinessInterfaceLocal businessInterface;
private void someMethod(){
PojoInterface pojo = new PojoClass(this.businessInterface);
}
and in my POJO class I have this constructor
BusinessInterfaceLocal businessInterface;
public PojoClass(BusinessInterfaceLocal businessInterface){
this.businessInterface = businessInterface;
//The following throws a Null Pointer Exception
this.businessInterface.someMethodCall();
}
Shouldn't the above work correctly? but it doesn't, the businessInterface object at the PojoClass is evaluated to null, and thus throwing a null pointer exception.
I was hoping if anyone could point me out, on what I'm doing wrong.
Thanks in advance.
verification
Is it possible you create the PojoClass before the EJB gets injected. By that I mean, where do you invoke "someMethod"? Is it in the constructor of the managed bean? A variable simply does not lose its referenced value.
You said you could see the BusinessInterfaceLocalbean isn't null in the Managed bean, can you verify you create the Pojo after that check?
Alternative solutions:
solution 1
You can use the POJO as a stateless bean, I don't see any problems in doing that, unless of course you are trying to use the POJO outside of your EE container, which is, by the looks of it not the case.
Making the POJO stateless would make you able to inject the EJB.
solution 2
OR a JNDI lookup, implemented as followed:
#Stateless(name="myEJB")
public class MyEJB {
public void ejbMethod() {
// business logic
}
}
public class TestEJB {
public static void main() {
MyEJB ejbRef = (MyEJB) new InitialContext().lookup("java:comp/env/myEJB");
ejbRef.ejbMethod();
}
}
With the code you show above, the only way that a NullPointerException could be thrown at the line indicated is if the businessInterface field in the managed bean is null. References cannot mysteriously become null when passed from one object to another, and the PojoClass doesn't do anything which would cause the variable to become null. I suggest you do some debugging or logging to definitively determine the value of the field in the managed bean at the point at which the constructor is called. If it is null, then the problem is with injection into the bean, and is not anything to do with the POJO, and you should fix that.
If the exception being thrown is actually from deeper than the line you show, then this could be a problem with the use of an EJB proxy in the wrong context. As you may know, a reference to an EJB is typically not a reference to the EJB itself, but rather to some sort of proxy which passes method calls on to the EJB; the proxy exists so that the container can step in and do things like start transactions, check authorization, and so on. The proxy may need to call on certain contextual resources to do its work which are available when the EJB is accessed from the managed bean but not, for some non-obvious and twisted reason, from the POJO. The unavailability of those resources could lead to a NullPointerException. Now, i think it is highly unlikely that simply passing a reference from a managed bean to a POJO would get you into that situation; this would only happen if you did something like accessing the managed bean from a different thread. So, it's probably not this!
The problem was caused by me trying to use the businessInterface object in the constructor, while the container injects the ejb only after it's done instantiating the managed bean,
reference to a similar question https://stackoverflow.com/a/6537228/1249304
What I did is that I created a method and annotated it with the #PostConstruct annotation, this way after the container is done with instantiating the managed bean, the annotated method gets called and the businessInterface object is no longer null
#PostContsruct
public void onInit(){
//businessInterface is no longer null
businessInterface.someMethod();
}
After constructing the bean, I want to retrieve data from the database, using the EntityManager. It is not possible in the constructor, because the EntityManager is injected after the constructor is called. So I tried to do it in a method annotated with #PostConstruct. According to the API, a PostConstruct Methods gets called after all injection are done. Executing the query works, but it always returns an empty list. If I use the same query in an other method, it returns the correct result. Does anybody know, why it does not work in the PostConstruct method?
#Stateful(mappedName = "price")
#Singleton
#Startup
public class PriceManagementBean implements PriceManagement {
#PersistenceContext
private EntityManager em;
private List<PriceStep> priceSteps = Collections.synchronizedList(new ArrayList<PriceStep>());
public PriceManagementBean(){
}
#PostConstruct
public void init(){
javax.persistence.Query query = em.createQuery("SELECT ps FROM PriceStep ps");
List<PriceStep> res = query.getResultList();
.....
}
}
Does anybody know, why it does not work in the PostConstruct method?
Reason 1
You cannot create a bean that is at the same time #Stateful and #Singleton(Well you can but it will make no sense since Singletons are also Stateful), that is one of the reasons you are having trouble. There is no exceptions, but there is a conflict in there, you need to fix that first.
Just remember:
A Singleton bean is a bean that mantains its state. There is only one instance of a Singleton in an application and it is shared among all the users of the app. Also since it is a shared(maybe better say concurrent) bean, there is need to implement some kind of locking mechanism using the #Lock annotation.
A Stateful bean is a bean that mantains each state after a transaction. When working with
Stateful beans each user gets a copy of the bean which will last as long as the session - lasts or until a method annotated with #Remove is called
Reason 2
Even if it works, you will be unable to access the results, because you are storing them in an object called res which is only accessible from inside the method init(). I suppose you would like to assign that returned value to the variable priceSteps.
Anyway there are many things wrong in your code, for not saying everything. I don't know what are your system requirements, but here i would give you a simple solution that will allow you to access the database:
I suppose you are trying to in some way return the data in the life cycle of the bean because you want to avoid sending queries again and again if the bean is #Stateful.
The thing is, you don't have to do that, you can still make your bean #Stateless and avoid stressing your database with many queries.
What you need to do is create a #NamedQuery.
So annotate your entity PriceStep with #NamedQuery and there enter the query string you wrote. In this link you will find information about how to use #NamedQueries:
http://docs.oracle.com/cd/B31017_01/web.1013/b28221/ent30qry001.htm
The next thing i would suggest you is to annotate your class PriceManagementBean as *#Stateless*. Don't worry if in each request a new entityManager is created, that does not stress the database at all, because it interacts with the domain model.
You don't need #PostConstruct, you just call your #NamedQuery whenever you need it and that's it. The app server will cache it and give it back to each user that requires it without interacting with the database all time.
Here a codesnipet:
#Entity
#NamedQuery(
name="allPriceSteps",
queryString="SELECT ps FROM PriceStep ps"
)
public class PriceStep implements Serializable {
...
}
Now the bean:
#Stateless
public class PriceManagementBean implements PriceManagement {
#PersistenceContext
private EntityManager em;
public List<PriceStep> getAllPriceSteps() {
Query query = em.createNamedQuery("allPriceSteps");
return query.getResultList();
}
}
I hope this is useful. If you give more information about your system requirements we could give you advice on a best practice.
Based on your requirement please try the following
Remove #Stateful [CAN'T use both at a time]
#Startup will initialize singleton bean during APPLICATION INIT [Please note the application was NOT fully initialized]. This might caused some issue in loading EntityManager and i assume the EntityManager bridge was not completely initialized. Try to call the init after complete application startup [i.e.,] Remove #Startup
I'm trying to get the clear picture of how this works:
-What is the advantage of using DAO class with DAO interface?
-How to handle Hibernate exceptions i.e
public String doSomething(){
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Query query = session.createQuery("");
Object o = query.uniqueResult();
session.close();
return "success";
}
I'm not "forced" to try/catch, so how do I catch/intercept any exceptions that may occur?
-Is opening session everytime for new DAO method more expensive than getting the current session? Should I close the session if I use get?
Question Update:
I have #Service annotation in my service classes and for each method using dao interface I've got #Transactional above. Also I've added #Repository to all my DAO classes
Update II:
I'm considering opening bounty for this questions because I want to know more details and this time I'll provide some.
Spring context
Controller
Service Interface
Service Implementation
DAO interface
DAO implementation
So I want to utilize spring MVC as much as possible, how do I make session opening/closing handled by #Transactional?
How do I catch the exceptions(i.e. non existing record or database failed) if any.
What I'm doing wrong? Can anyone suggest some improvements?
A few things on the hibernate session side...
1.) I would take a look a integrating Spring's transaction management into your project. This way you don't have to worry about opening and closing your session's because Spring will handle this for you with intercepts using the #Transactional annotation.
2.) If spring is handling your transactions you won't have to worry about doing the finally calls to make sure everything is closed or rolled back.
3.) If you decide not to use Spring to manage the sessions you should not keep it open for any extended period of time but again, if you use Spring you don't have to worry about it.
As far as the interface on the DAO classes i offer this...
1.) It is considered a good design practice to code to interfaces (see comments left below) and here are a few good reasons why.
lets say you have a...
public interface ShoppingCartService{
public void doStuff(Object obj);
}
You could expose this service as a servlet and deal with the just the 'contract' your interface creates or even hide the fact your using Hibnerate, JDBC or anything else...
#Service
public class PetShopShoppingCartService implements ShoppingCartService{
#Transactional(propagation=Propagation.REQUIRED)
public void doStuff(Object obj){
//The Pet Shop service impl uses hibernate!;
}
}
or...
public class DrugStoreShoppingCartService implements ShoppingCartService{
public void doStuff(Object obj){
//The Drug Store service uses JDBC;
}
}
Or even...
public class NextBigThingShoppingCartService implements ShoppingCartService{
public void doStuff(Object obj){
//do stuff with next big thing;
}
}
I think you get the picture. If you developing public api's or exposing services this becomes pretty important.
Lastly, another good reason to have the interfaces is with working in a team of more than a couple developers. You can quickly stub out an interface, check-in and tell everyone else that this is how it's going to look. This allows them to see what's important and even mock their own impl if they need to (ThingServiceMockDataImpl)
Just because you're not forced to catch exceptions when using Spring's HibernateTemplate doesn't mean that they will not get thrown. They will just be RuntimeExceptions instead of checked exceptions. Also, getCurrentSession() does not open a new session each time you call it, it returns the local Thread's Session.
There are lots of advantages, including lack of code coupling, encapsulation, and transaction demarcation for using the DAO strategy instead of putting your data access code directly into your controller. See http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html for more info.
Environment: Spring 3, Custom Transaction Management, JDBC Transactions
I just read the Spring docs on using the transaction template to handle transaction management. It seemed overly complex so I want to ask:
Most of my transactions are JDBC related, meaning I just declare an #Transactional on my service. But now I am making a REST service call to another site which needs to rollback if any of the following JDBC operations fail, I'll provide the rollback code in this case.
As I progress in my method, in my transaction - I want to save a reference to the REST service call (needed to roll back that action), and upon exception I just want a method myCustomRollback() called which can access the previously stored object.
Why not just provide a map in the transactionTemplate for storing stuff and define a custom rollback method on the #Transactional annotation?
This is the way I think about it, I'm not following the way Spring thinks about this. Can someone help me bridge the gap between what I want and how I accomplish it most efficiently in Spring? I only need to do this for a few special case operations.
To anyone still reading this:
I solved a similar problem with spring events - as suggested by Den Roman in option 3.
Here's the basic idea (scenario is fictional):
Whenever I perform external operations that need to be rolled back together with the transaction, I publish an event inside my #Transactional method using support from spring (org.springframework.context.ApplicationEventPublisher):
#Transactional
public String placeOrder(Order order) {
String orderId = orderServiceGateway.createOrder(order);
applicationEventPublisher.publishEvent(new OrderCreatedEvent(orderId));
workflowService.startWorkflow(orderId);
return orderId;
}
The event itself can be any object - I created a POJO with details about the remote entity to be deleted.
Then I registered a special event listener that is bound to a transaction phase - in my case to the rollback:
#TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void rollBackOrder(OrderCreatedEvent orderCreatedEvent) {
String orderId = orderCreatedEvent.getOrderId();
orderServiceGateway.deleteOrder(orderId);
}
Of course, it's recommended to catch & log the exception from rollback operation, not to lose the original exception from the placeOrder() method.
By default these events are synchronous, but they can be made async by additional configuration.
Here's a very good article on this mechanism, including detailed configuration and pitfalls: Transaction Synchronization and Spring Application Events (DZone)
While I don't like the solution 100% because it clutters the business logic with event publishing stuff and binds to spring, it definitely does what I expect it to do and makes it possible to pass context from the transactional method to the rollback method - which is not available through a traditional try/catch block outside of the transactional method (unless you put your context in the exception itself, which is not very nice).
I've re-read your question a few times and am not sure I understand your question completely. I assume your executing someCode and if that fails you would like to execute myCustomRollback which has some information about someCode. So I'll try to provide a Generic answer.
If you want spring to rollback some code. It will only rollback that which is rollBackAble, like jdbc transactions. Assume you have a method which performs 2 calls.
#Transactional
public void doStuff(SomeEntity entity, File file) {
persist(entity);
customFileService.createOnFileSystem(file);
throw new RunTimeException();
}
So the code above will always rollback. It will undo the persisting of your entity, but not the creation of your file, since that is not managed by Spring transactions, unless you provide custom implementation for it to be.
Second, Spring provides 2 ways of working with transactions:
Spring AOP: a proxy is created at runtime which will decorate your code with transactional stuff. If your class would be named MyClass, then Spring will create a class names MyClassProxy, which will wrap your code in transactional code.
AspectJ: at compile time your .class file will be adjusted and transactional code will be embedded inside your method.
The aspectJ approach seems harder to configure, but isn't so much and is way easier to use. Since anything which is annotated with #Transactional will be embedded (weaved) with code. For Spring AOP this is not the case. Transactional inner method calls for instance in Spring will be ignored! So aspectJ provides a more intuitive approach.
Back to what I think your question is (the code is all in 1 class):
public void doSomeCode() {
Object restCall = initialize();
try {
execute(restCall);
} catch (CustomException e) {
myCustomRollback(restCall; e);
}
}
#Transactional(rollbackFor = CustomException.class)
private void execute(Object restCall) throws CustomException {
// jdbc calls..
restCall = callRest(restCall);
throw new CustomException();
}
void myCustomRollback(Object restCall, CustomException e) {
...
}
The code above will only work with AspectJ! Since your making inner method calls which also seems to be private! AOP at runtime cannot handle this.
So what happens is everything (which is rollbackAble) in execute will be rollbacked. And in doStuff you have information about the objects which were used in execute, you now can use in myCustomRollback to rollback your REST stuff manually.
Not sure if I answered this question properly, but I hope it helps someone with a similar problem.
1 solution is to implement your own transactional manager by extending a one
2 solution is to use TransactionSynchronizationManager class
3 solution is to use #TransactionalEventListener in case you have Spring 4
Spring transaction management the default behavior for automatic rollback is for unchecked exceptions
so for a custom exception,
#Transactional(rollbackFor = CustomException.class, noRollbackFor = RuntimeException.class)
public void doSomething(...
)
the transaction be rolled back if it there is an exception that matches the specified. If an exception not matches, it is propagated to caller of the service or TransactionRolledBackException wrapper
if you use use the org.springframework.transaction.PlatformTransactionManager it is more manageable handling exceptions than template
check the documentation http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html
you can use the AfterThrowing advice (when an exception is thrown) & call your method (myCustmRollback()) there, you can use TransactionSynchronizationManager class to get thecurrent transaction & roll it back...
alternatively.. you can use the AroundAdvice to begin & commit/rollback your transaction (this way you can use the spring provided transaction manager by using the TransactionSynchronizationManager class)