I'm having troubles in integrating Vaadin and spring-data (JPARepositories in particular).
After following the guidance of Vaadin's team with their last webinar I managed to configure my application using Spring starter (spring boot), adding Vaadin, JPA and a Postgresql database. Using this method was really straightforward and loading entities to a table works out of the box by simply having this
#Autowired private ProjectDAO projects;
// other code here ...
grid.setContainerDataSource(new BeanItemContainer<Project>(Project.class, projects.findAll()));
My repository is just
#Repository
public class ProjectDAO implements JPARepository<Project, Long> {
}
And, as I said, this works flawlessly. The problem is when I try to save something: when trying to save a project via a button click, for example
btnSave.addClickListener(e -> saveCurrent());
private void saveCurrent() {
// ... here I do some filesystem operations, nothing that requires DB connection
setModified();
}
public void setModified() {
project.setLastAccess(new Date());
projects.saveAndFlush(project);
}
I get an exception:
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress.
I've tried many different things, such as marking the setModified method as #Transactional, or encapsulating the setModified into a service class, but everything always throws this exception.
I find it rather strange that this doesn't work "out of the box", and I'd rather not work with transactions myself, since there are already the instruments to do that.
Any help would be really appreciated
EDIT 12/05/2015
It seems that this problem only appears when using an external server, not the embedded one provided by spring-boot. For test purposes I can manage to use the built-in, but eventually I will have to deploy the application on an existing server, so what could the issue be? Tomcat's configuration?
If anyone needs the answer I'll leave here what I found out after a few days of breaking my head on it.
Before deploying the application I changed some configurations on the main class that was generated by Spring Initializr (The application one) and made it extend SpringBootServletInitializer because I was following the guide I found in the official spring blog. Turns out that this was in fact not necessary because I set up "WAR" in Spring Initializr from the beginning, thus the application already had a class extending that one, and as a result when deploying it on Tomcat, the web application started twice, so the application was configured twice and two persistence units were instantiated. This probably was the error, because after reverting the changes I made to the application everything worked fine.
TL;DR: if you use Spring Initializr to create a WAR application don't touch anything.
Related
I am creating an internal CLI that is communicating with a PostgreSQL database and the easiness to create a no-code repository is one of the features that convince me to choose Spring data JPA.
However, I am not able to find some tutorial or GitHub repository to set up a Spring data JPA project without an entire spring boot application.
On the project https://github.com/spring-projects/spring-data-book/tree/master/jpa there is no main entry point, so the code is not runnable and by the way, it was updated 8 years ago ...
This other StackOverflow thread Spring Data JPA without Spring Boot does not help me because the guy could run his spring application on Google Cloud Platform finally (that was the cause of why he ask how to setup sping data jpa without spring boot).
I don't know how to start, if you have any ideas I will be happy to discuss with someone who is more experienced than me.
Thank you.
This might help if no more complete tutorial turns up https://docs.spring.io/spring-data/jpa/docs/1.5.0.RELEASE/reference/html/repositories.html
Look for this section
Standalone usage
You can also use the repository infrastructure outside of a Spring container, e.g. in CDI environments. You still need some Spring libraries in your classpath, but generally you can set up repositories programmatically as well. The Spring Data modules that provide repository support ship a persistence technology-specific RepositoryFactory that you can use as follows
In particular it says you can use a factory to generate repositories:
RepositoryFactorySupport factory = … // Instantiate factory here
UserRepository repository = factory.getRepository(UserRepository.class);
So adding the spring parts that contain the spring data classes may be enough for this level and if you want to have DI, too, you likely need to combine them with the respective spring dependencies and configure a regular spring application.
We have a Spring-Boot application exposing some REST endpoints. We allow for this application to be operated standalone (as executable jar) or as a war to be deployed in a wildfly-11 application-server.
The class defining the REST-endpoints is marked #RestController #Transactional(REQUIRES_NEW) (both on class level, obviously). When running standalone, everything works as expected but when deployed in wildfly, the rollback on exceptions does not work. We established this by sending the exact same REST-message while operating on the exact same database.
We have confirmed via debugging that the final frames of the stacktrace is identical in both cases and especially in both cases we see a transactional-proxy around our REST-controller bean.
One difference would be, that within wildfly the application will use a jndi-datasource, prepared by wildfly while standalone the spring-boot will manage the database-connections.
Any idea what is wrong here?
Edit
I just tried explicitly invoking setRollbackOnly on the JtaTransactionmanager from within my code. The transaction will still commit. This sort of looks like a bug in Spring Boot to me.
Edit 2
Debugging further reveals that the transaction seems to be set to autocommit - every statement is immediately written to the database. This seems to be in violation to the annotation #Transactional and also to the fact that Spring creates a transactional proxy around my bean.
It's not a full answer - just a reasoning. JNDI is usally used at the app server layer whereas JDBC - at the application layer. At the App server layer are used global transaction settins that are overriding app settings. Follow the spring doc to get more
For reasons beyond my understanding the default transactional behaviour when deploying a spring-boot webapp to an application-server is auto-commit.
The solution to this problem is to enrich your application-configuration with the property spring.datasource.tomcat.default-auto-commit=false
I'm fairly new to Java--though, coming from PHP + JS. I aim to make a CRUD (+MVC) with Java Servlets.
I am using Java EE 7. I based some of my patterns here with this and that (both have the same final files).
So, I am implementing MVC, and I can't seem to make my code to work. JPA seems to be the main issue; I can't fetch anything from the database.
Here's the repository (really small project -- 7~8 classes). Models; DAO.
I had setup controllers.Test(url: /test) to test if I could actually communicate with the database via JPA. However, when I go to /test(controllers.Test), an exception is thrown. The same goes for controllers.NewsEdit(url: /edit).
java.lang.NullPointerException
controllers.Test.doGet(Test.java:36)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
When I visit home(url: /; controller.NewsIndex), I receive no exceptions -- I get the homepage, but no data at all. Is there anything I'm doing wrong?
My SQL files are located in the /sql folder. I got persistent.xml on META-INF/.
Any help or reference would be appreciated. Really need to learn it..
Thanks!
Ok,
A lil explanation about NullPointerException.
When the variable (in this case private NewsDAO newsDAO;) hasn't been initialized, that "pointer" is pointing to nothing in memory. Then when you try to call a method, there is nothing there and the NPE happens.
The problem here is that private NewsDAO newsDAO; is not being injected by the container and therefore when you call newsDAO.all(); newDAO is null and throws the exception.
CDI Injection only happens for components managed by the containers. I'm a spring guy so I'm not sure where to go here. Try to figure out if your NewsDAO is being loaded by the container.
Tomcat is a web container... You need a full Application server with an EJB container to run your example. Try to download and run on glassfish, JBoss or any other full app server.
more info here.
http://en.wikipedia.org/wiki/Application_server#Java_application_servers
and
http://www.oracle.com/technetwork/java/javaee/overview/compatibility-jsp-136984.html
I have a Swing project using Spring for DI and now I am trying to migrate to Eclipse 4 and OSGi.
Using the configuration files of Spring the user could comment/uncomment beans in order to add/remove functionality (offered by these back-end beans).
Now in Eclipse and OSGi I am looking for the best way to do this based on OSGi.
I know that I can make the beans as services and define start levels in OSGi but this does not solve my use case, which is:
The application starts without these beans/modules running and if the user updates the configuration from the running UI these beans/modules start and they are also started on the next start-up of the application.
Is there a nice/clean approach for my problem?
You probably want to use Eclipse Gemini Blueprint to do the management of how everything is integrated between Spring and OSGi (Gemini Blueprint is the successor to Spring Dynamic Modules). In particular, it can handle virtually all the complexity relating to dynamic service registration for you; your beans can remain virtually identical.
Another approach would be to use Declarative Services together with Configuration Admin to let configuration data determine which services to activate. In more detail here.
Like you already found out services are a good aproach to this. Simply install all your modules but do not start them. Then your UI can start and stop modules as the user selects the functionality he wants. THe OSGi framework then remembers the installed and started modules on a restart.
The absolute best approach for this is Declarative Services (DS). DS is integrated with OSGi's Configuration Admin, making it trivial to control the number of service instances as well as their configuration and service properties. For example, the following component (with the bnd annotations [which will resemble similar functionality in the OSGi specs soon]):
#Component(designateFactory=Config.class)
public MyComp implements MyService {
interface Config {
int port();
String host();
}
Config config;
#Activate
void activate(Map<String,Object> map) {
config = Configurable.createConfigurable(Config.class,map);
start();
}
void foo() { ... do the MyService stuff ... }
#Reference
void setDataSource( DataSource ds ) { ... }
}
This component requires a Configuration Admin factory configuration. The best way to see how powerful this is, is to setup a framework with Apache Felix Webconsole. The designateFactory=Config.class tells bnd to create a metatype XML file in the bundle. This is used by the Webconsole to create a pretty nice looking form for the configuration data, derived from the interface and its methods. This form is type aware, i.e. you cannot enter a non-nummeric value for the port number. Through the webconsole you can now instantiate multiple components by creating multiple factory configurations. Deleting these factory configurations, removes the service. In your application, you can manipulate Configuration Admin yourself under the control of the user.
Another advantage is that through Configuration Admin you can control the binding of the component's dependencies. In the aforementioned example, you can set the dataSource.target property to a filter like (db=accounting) to select the accounting database. All configuration properties are added as service properties so you can easily set the 'db' service property on the configuration that creates the Data Source (if it was implemented this way).
This is one of the least understood advantages of DS, and I can tell you it is HUGE. To get started with this this, just create a DS project in bndtools and then a new Run Descriptor and select the Webconsole template.
Another advantage of DS is that it is small and it is not try to hide the dynamics, which in Blueprint can be painful.
I have an app using Wicket for the presentation layer with CDI/Weld, JPA 2.0, EJB 3.1 etc. (Java EE 6) deployed on GlassFish v3.0.1.
When I try to inject an EJB into a wicket page using #EJB I get the following error:
java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName
When I try to inject using #Inject, I get the following error:
java.lang.IllegalStateException: Unable to convert ejbRef for ejb UserRepository to a business object of type class
I believe the problem is stemming from JPA. I am using the exact same configuration that I used with a JSF application which worked properly, so I am lost as to what the issue could be. The connection pools are set up properly and pinging correctly through GlassFish, I have included wicket-weld on the classpath and I have even tried using the old Java EE 5 wicketstuff project for wicketstuff-javaeeapi with the same results.
Any help would be appreciated.
If you get the exception:
Unable to retrieve EntityManagerFactory for unitName
It might mean it is not detecting your persistence.xml file. Make sure it's in the WEB-INF\classes\META-INF directory.
You can verify that your app has JPA enabled by going to the Admin Console in GlassFish, go to the Applications section and see if it shows something like [ejb, web, weld, jpa] for your app. If it doesn't show jpa then it's not finding your JPA config file.
Could always try to lookup the EJB via its standard "java:global" name. That should at least let you rule out wicket as a possible source of issues and get you a little closer to a working system.