Weired world... let me try:
I have the follwing mavenized setup:
- Springboot (1.5.5.RELEASE)
- Hibernate (5.0.9.Final; I do know there is newer variants but I stick with what I have right now)
- ExtJs (6.0.0)
- IntelliJ (2017.3)
I do partly get running into an Hibernate Exception:
2018-11-20_15:04:58.007 [http-nio-8081-exec-7] [ERROR] o.a.c.c.C.[.[.[/].[dispatcherServlet]:181 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException:
Could not obtain transaction-synchronized Session for current thread] with root cause
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:133)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:697)
...
This does not happen on all threads! Partly the requests from ExtJs go through, Partly they don't. But would they not open a transaction on the webserver side?
I do have an Interceptor; well a web Interceptor implementing org.springframework.web.servlet.HandlerInterceptor
Within the interceptor's preHandle method I do call a Service in order to check if a user is logged in and do some rights management handling.
The called #Autowired service fails. I thought the fact of accessing an #Autowired service method takes care of session/transaction handling.
Well, this was the scenario having my project manually created and run with a java-8 (java 8 sdk; not 9, not 10, not 11) command like from the console:
mvn clean package -DskipTests && java -jar target/MyBuild.jar application-local.properties
I just observed that the login consists of three request from browser to the backend. These three are all handled in separate threads by the backend.
When running the project within IntelliJ it all works fine. Ok, IntelliJ most likely does not jar the application and builds its own startup command.
But exactly that brings me out of rhythm due to the fact that we do process the code through a deployment / CI pipeline where we manually build the project.
And that is where it fails :-(
Amendment:
I changed everything to run with JPA instead of Hibernate (well it is still hibernate in the background). Just as 'M. Deinum' suggested.
Now, the problem still exists.
Two things I somewhat extracted.
In my Interceptor I do have some logging calls which ask the EntityManager for a hibernate-session (entityManager.unwrap( Session.class )).
This is the point where now.
So it seems that on the preHandle(...) of my interceptor there is sometimes no current session active. I am stating 'sometimes' since there are calls to the Interceptor when it works.
The exception comes as following now:
java.lang.IllegalStateException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:272)
at com.sun.proxy.$Proxy117.unwrap(Unknown Source)
at com.mypackage.dataaccess.DataAccessImpl.getCurrentSession(DataAccessImpl.java:89)
at com.mypackage.dataaccess.DataAccessImpl.queryByHQL(DataAccessImpl.java:382)
Ok. I ended up noting all Spring web controllers to have an #Transactional (where DB usage is given.)
That works.
From my understanding it does not matter where to put the #Transactional annotation as long as the method/owning Object is invoked through spring's #Autowire mechanism.
If I want something to run under the transactional behaviour I would annotated with it on the closest scope possible.
That's how I would decide where to put the #Transactional
At the end it does work but I am not satisfied with the solution.
If anyone could clarify the behaviour and/or my understanding let me welcomely know :-)
Related
We've been working on an application that uses Tomcat 8 throught connection pool. We control Optimistic exceptions with #Version field, and we control transactions with Entitymanagers isolated by ThreadLocal.
However, the application triggers a concurrency exception sometimes with hangs other processes and requieres to restart the server.
The exception is always like this:
Caused by: Exception [EclipseLink-2004] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6):
org.eclipse.persistence.exceptions.ConcurrencyException
Exception Description: A signal was attempted before wait() on ConcurrencyManager. This normally means that an attempt was made to commit or rollback a transaction before it was started, or to rollback a transaction twice.
at org.eclipse.persistence.exceptions.ConcurrencyException.signalAttemptedBeforeWait(ConcurrencyException.java:84)
at org.eclipse.persistence.internal.helper.ConcurrencyManager.releaseReadLock(ConcurrencyManager.java:468)
at org.eclipse.persistence.internal.identitymaps.CacheKey.releaseReadLock(CacheKey.java:475)
We've been trying to solve this problem or find any specific information about this error with no result. We even followed instructions in https://wiki.eclipse.org/EclipseLink/FAQ/JPA#How_to_diagnose_and_resolve_hangs_and_deadlocks.3F.
Disabling cache seems to solve the problem, but we cannt afford to not use cache due to performance needs.
Any help would be appreciated.
Thanks
Finally, after six months of headaches, I managed to solve the problem.
The general error was EclipseLink-2004. If you check Eclipselink error reference:
Eclipse link error reference page, it says "Verify transactions in the application".
I've been using a application managed Entity Managers. To control that transactions were single-thread I used this ManagerHelper class:
EntityManagerHelper
The problem was that I was putting a managed object inside a Session attribute. I don't really understand the process inside, but somehow it created new transactions outside the main transaction if it was used to query. Moving the object to Request attributes solved the problem.
I hope this helps to someone in the future.
Best regards
We have a spring web-application running on a Tomcat server that we would like to have some additional code run ONLY if there is an issue with the webapp's startup.
However, any errors we receive will come from either Bean Creation Issues (which, hopefully we would catch before ever releasing) or a Flyway upgrade script issue. Both cases, the exceptions are caught within the spring core somewhere, and I'd like to run some additional code in those situations before the webapp failure finishes. I'm not 100% sure how to set this up though, considering where the exceptions are thrown.
I've been looking at Spring's Life Cycle configuration annotations, and while I have considered running the code in the #PreDestroy method we're providing, that means it would run our code every time we restarted the webapp, instead of just on startup failures. Is there a way to indicate the differences between a normal shutdown and a failed startup using the life cycle annotations?
You could register your own ServletContextListener instead of the Spring's one and delegate contextInitialized method invocation to the Spring implementation you use for loading Spring context (whichever one you use, for example org.springframework.web.context.ContextLoaderListener).
Then catch and handle the desired exceptions.
Trying to get my head around Java EE (ORM/Entities/Annotations/EJB/Servlets etc.). So I've created a very simple webpage where you can enter user information and send it to the server. I'm using Apache Tomcat 8.0 as webbserver application and here is all the relevant parts of the application files and content that is needed to persist an entity:
http://pastebin.com/fwfbnYpU
The application gives me the error on line 99 saying:
08-Apr-2014 16:18:10.329 SEVERE [http-nio-8084-exec-93] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [indexServlet] in context with path [/JavaEENackademin] threw exception
java.lang.NullPointerException
What am I doing wrong? The database exist with the correct named table and columnnames. But then again that is not the problem here maybe it will become a problem after I fix this problem :)
One issue with your code is that you should not inject EntityManagers into servlets. Servlets are usually singletons, so all servlets would use the same EntityManager. You should inject an EntityManagerFactory instead and get your EntityManagers from it. You also have to take care of transactions. Not sure if this has caused your issues, but something that should be fixed.
I'm surprised you are able to deploy the code in your pastebin. Especially:
#WebServlet(name = "indexServlet", urlPatterns = {"/indexServlet"})
public class indexServlet extends HttpServlet {
#Inject
LoginValidation validation;
#PersistenceContext(unitName = "JavaEENackademinPU")
private EntityManager em;
//... offending line 99 calls: em.persist()
}
Neither PersistenceContext nor Inject are part of the servlet spec, so you probably added additional jars to your installation.
But you configured your persistence.xml to use JTA transactions which are barely supported in a servlet environment, probably resulting in tomcat ignoring the #PersistenceContext annotation altogether and leaving em == null (the default value).
I've found this link describing an integration but it looks complicated, requires editing internal xml files and then goes on to use Spring. Likely every part of that is overkill for a beginner.
I suggest you start fresh with a copy of TomEE which already does all the wiring to get you a fully fledged application server that supports CDI (#Inject) and JPA (#PersistenceContext) out of the box.
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 mantaining a EJB 2 CMP legacy app runing on a JBoss 4.0.4 GA application server with deployed entity/stateless session beans. All the EJB boilerplate code is generated via XDoclet from the EntityEJB/EntityEJBManager annotations.
I've noticed that when my GUI client invokes the facade create method, I have lots of cases of EJBException in my server log with the "Reentrant method call detected" message, which rollbacks the transaction.
What does this Exception means? How can I avoid having such error (which unfortunately, I wasn't able to reproduce yet)
Update: Found this link that explains what is meant by reentrancy, however, seems to me that it says my app cannot be accesed concurrently?
I've seen this before where EJB1 calls EJB2 which calls back to EJB1 within the container as part of the same transaction.
You can tell the container to allow this by marking EJB1 as reentrant which will allow it to be accessed multiple times in the same transaction.
This is done in the deployment descriptor with the following tag:
<reentrant>True</reentrant>
There should be a corresponding EntityEJB annotation that XDoclet can use to generate this for you.
we just came across the same problem and our solution was two-fold. Firstly we ensure that none of ejb's had transaction attributes of NotSupported within our ejb-jar.xml. We then used "instance per transaction" as our optimistic locking strategy. It's a bit of a belt-and-braces approach, but it works
It does mean that the Entity bean in question cannot be accessed concurrently, which makes sense since it would likely corrupt the data.