Composite Persistence Unit using a single JAR file - mysql

I have searched the web and this site already for an answer. Although I found one link through a Google search, I subsequently lost the link and can't find it again.
I have been working on an e-commerce web site running on Glassfish 4.1.1 that originally had a single database (DB) using EclipseLink 2.6.4, but it now requires three that will reside on multiple servers (in order to keep customer data secure). The site worked fine with the single DB. I split the data from the single DB into three. The entities and JPA controllers defined in the J2EE code are all the same (I preserved the code so I wouldn't have to rewrite everything, only make minor changes such as annotations, etc.), but they are now located in three different MySQL databases. The three databases have relationships to one another.
In theory (and according the the link I saw and lost) a composite persistence unit (PU) can be defined to incorporate all three PU's for the three different data sources all within a single JAR file and using tags for the entity-PU mappings. Most of the examples (and the Eclipselink and Oracle Persistence API documentation) use a Composite PU with multiple JAR files (e.g.: https://github.com/forgemo/eclipselink-composite-persistence-unit-example).
Can anyone point me in the right direction as to how to create a composite PU without having to use a separate JAR file for each database PU?
My current persistence.xml file (musltiple PUs but not a composite) is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
>
<persistence-unit name="PU1" transaction-type="JTA">
<jta-data-source>java:app/jdbc/db1</jta-data-source>
<class>com.mysite.myproject.Database.Items</class>
<class>com.mysite.myproject.Database.Manufacturer</class>
<class>com.mysite.myproject.Database.Category</class>
<class>com.mysite.myproject.Database.Cart</class>
<class>com.mysite.myproject.Database.AuditTable</class>
<class>com.mysite.myproject.Database.Images</class>
<class>com.mysite.myproject.Database.Procedures</class>
<class>com.mysite.myproject.Database.Warehouse</class>
<class>com.mysite.myproject.Database.Wishlist</class>
<class>com.mysite.myproject.Database.Purchases</class>
<class>com.mysite.myproject.Database.TaxTables</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
<persistence-unit name="PU2" transaction-type="JTA">
<jta-data-source>java:app/jdbc/db2</jta-data-source>
<class>com.mysite.myproject.Database.AccessList</class>
<class>com.mysite.myproject.Database.Users</class>
<class>com.mysite.myproject.Database.Customer</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
<persistence-unit name="PU3" transaction-type="JTA">
<jta-data-source>java:app/jdbc/db3</jta-data-source>
<class>com.mysite.myproject.Database.Key1</class>
<class>com.mysite.myproject.Database.Key2</class>
<class>com.mysite.myproject.Database.Key3</class>
<class>com.mysite.myproject.Database.Key4</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
The above persistence.xml works fine as long as there are no relationships between data sources (e.g. - relationship between Wishlist and Customer tables results in "[class com.mysite.myproject.Database.Wishlist] uses a non-entity [class com.mysite.myproject.Database.Customer] as target entity in the relationship attribute [field customer]" at deployment).

As it turns out, it seems a composite persistence unit is not needed (which probably explains why nobody can answer the question and there is little documentation about them).
After finding many, many bugs in Glassfish, Geronimo, WebLogic, and Ecplipselink, and NetBeans, I was finally able to get the system working using multiple persistence units (PU) without using a composite PU. JTA is able to persist all entities including their references to entities outside their own PU. One key factor to making this work is to make sure classes not part of a PU are NOT excluded by adding this to your PU definition in persistence.xml:
<exclude-unlisted-classes>false</exclude-unlisted-classes>
as in the following complete PU example (one of the three I use in my project):
<persistence-unit name="DHWPU" transaction-type="JTA">
<jta-data-source>jdbc/dhw</jta-data-source>
<class>Database.AuditTable</class>
<class>Database.Cart</class>
<class>Database.Category</class>
<class>Database.Images</class>
<class>Database.Items</class>
<class>Database.Manufacturer</class>
<class>Database.Procedures</class>
<class>Database.Purchases</class>
<class>Database.TaxTables</class>
<class>Database.Warehouse</class>
<class>Database.Wishlist</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="none"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>

Related

How to show differences between entities and database table structure

I am currently working on a system that has been around for a number of years and has gone through a fair amount of transformation. (GWT\Spring\Hibernate). I recently had to merge two entities as part of a change. When I looked at the actual sql tables I noticed that there were a number of orphaned columns that were actually not mapped to the entities and could effectively be dropped. I was wondering if there are any tools out there that would help us to identify and strip out outdated columns which are not actually being linked to our entities.
If you´re Using Spring and hibernate you can use autodetection to create/update database though the entities attributes that you have in your entity.
your hibernate.hbm2ddl.auto setting should be defining that the database is created (options are validate, create, update or create-drop)
Here the Spring configuration:
<?xml version="1.0" encoding="UTF-8"?>
<persistence-unit name="NewPersistenceUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/Icarus"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hbm2ddl.auto" value="create"/>
</properties>
<class>net.interaxia.icarus.data.models.ServerNode</class>
</persistence-unit>

Why isn't hbm2ddl.import_files working in hibernate4-maven-plugin (Hibernate 4.3.6)?

I have the following 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="blah" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.hbm2ddl.import_files" value="myfile.sql"/>
</properties>
</persistence-unit>
</persistence>
But the hibernate.hbm2ddl.import_files property isn't working. Doesn't seem to matter where I put myfile.sql or prepend with a slash or even wildcards, classpath etc. (clutching at straws) - it never finds it and the log output doesn't indicate it is even looking for it. The default import.sql is used instead (and works).
Note: Have seen similar questions (e.g. this and this) but none of the resolutions worked for me.
I now think this problem is due to using the hibernate4-maven-plugin - it doesn't seem to support all the Hibernate properties.

Checkstyle different rules for different files

I have one file which contains rules for the project.
I want my unit tests methods to be allowed to have underscore in their names.
Like myMethod_should_call_someClass_someMehod. Currently I have one configuration, which is applied to all files in the project.
My question is it possible to somehow configure checkstyle, so, for example I specify specific rules for all files that are ending with *Test.java.
Currently the only solution I found is to provide SuppressionFilter and exclude all files ending with *Test.java. But is there a way I could provide a different MethodNameCheck module with different format for test files?
You must define the MethodName check twice, with one instance checking the regular methods, and the other checking the test methods. Note the id property, which we will use to restrict the checks to their respective domains:
<module name="MethodName">
<property name="id" value="MethodNameRegular"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
</module>
<module name="MethodName">
<property name="id" value="MethodNameTest"/>
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
</module>
Next, the regular check must be suppressed for test methods and vice versa. This works only if you have a criterion by which to distinguish between the two kinds of classes. I use the Maven directory convention, which puts regular classes under src/main and test classes under src/test. Here is the suppression filter file:
<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files="[\\/]src[\\/]test[\\/].*" id="MethodNameRegular" />
<suppress files="[\\/]src[\\/]main[\\/].*" id="MethodNameTest" />
</suppressions>
Building on barfuin's answer, I preferred not to have (yet) another XML file floating around. However, it is possible to configure suppressions directly in the CheckStyle XML config file:
<module name="SuppressionSingleFilter">
<metadata name="net.sf.eclipsecs.core.comment" value="Suppress MethodNameRegular check on unit tests"/>
<property name="files" value=".*[\\/]src[\\/]test[\\/]"/>
<property name="id" value="MethodNameRegular"/>
</module>
<module name="SuppressionSingleFilter">
<metadata name="net.sf.eclipsecs.core.comment" value="Suppress MethodNameTest check except on unit tests"/>
<property name="files" value=".*[\\/]src[\\/](?!test[\\/])"/>
<property name="id" value="MethodNameTest"/>
</module>
(This would be in addition to the two MethodName checks.)

Spring JPA doesn't store entity

I created a basic Spring MVC / JPA / Hibernate app. I am trying to save a UserProfile entity to test if I can actualy persist it, but nothing gets saved and no exception is thrown either.
In the controller method I create a simple UserProfile (which is an #Entity) and I am sending that to a service method. The UserProfileServiceImpl class is annotated with #Service and the addUserProfile(UserProfile profile) method is annotated with #Transactional.
In the service method, all I do is call a DAO method (class annotated with #Repository). In the DAO method all I do is call entityManager.persist(object), with object being the user profile object.
Nothing gets written to the server log and the log level is at INFO.
Nothing appears in the Mysql query log (and I know the query log works)
The entityManager gets properly injected.
The datasource is properly initiated, because when I enter faulty credentials I get SQLExceptions.
I hope you can tell me what's wrong. I'll post some of my code and config files below.
The service method:
// The service method gets called from the controller.
// Its class is annotated with #Service
#Transactional(readOnly = false)
public void addUserProfile(UserProfile userProfile) {
userProfileDao.save(userProfile);
}
The Dao method:
// The save(T object) method is in the GenericDaoJpa class, which is the superclass
// of the UserProfileDaoJPA class that is referenced from the service.
// I have established that the entityManager is there and the object is a
// UserProfile. The #Repository annotation is on the child class UserProfileDaoJpa.
public void save(T object) {
entityManager.persist(object);
}
Main application-context.xml
<context:property-placeholder location="classpath*:**/*.properties"/>
<import resource="spring-jpa.xml"/>
The application-context-web.xml file
<mvc:annotation-driven />
<context:component-scan base-package="nl.codebasesoftware.produx" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
spring-jpa.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${db.driverClassName}"
p:url="${db.url}" p:username="${db.username}" p:password="${db.password}"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
persistence.xml
<persistence-unit name="mysqlPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
<!-- Needed to properly process #PersistenceContext -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
Somehow no SQL is sent to Mysql with this setup, but no exception is thrown either, so I have no idea what's going on. Hope you can help :)
i think you are missing transaction propagation at service. marking readonly=false just set session to auto flush. but setting up proper transaction propogation will make sure start of trnasaction and commit/rollback.
after removing mode="aspectj" it has started working because i think because of as per spring doc
The default mode "proxy" will process annotated beans to be proxied
using Spring's AOP framework (following proxy semantics, as discussed
above, applying to method calls coming in through the proxy only). The
alternative mode "aspectj" will instead weave the affected classes
with Spring's AspectJ transaction aspect (modifying the target class
byte code in order to apply to any kind of method call). AspectJ
weaving requires spring-aspects.jar on the classpath as well as
load-time weaving (or compile-time weaving) enabled. (See the section
entitled Section 6.8.4.5, “Spring configuration” for details on how to
set up load-time weaving.)
and probably you have not configured load time weaving
Ok, I got it. First I thought I found the answer here
Declarative transactions (#Transactional) doesn't work with #Repository in Spring
But after some more testing I found it was not the location of
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
but its contents.
After removing the mode="aspectj" attribute it started working! If anyone would like to comment why that is, please do.
Let me share my full setup with you. This is for Spring 3.1 with Hibernate 4. NOTE: for 'brevity' I only posted the contents of the configuration files, and omitted the outer tags <beans> and <persistence> and the namespace declarations. I removed spring-jpa.xml altogether and moved its contents into application-context.xml.
Contents of web.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<display-name>My Spring MVC web application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:**/application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>produxDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:**/application-context-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>produxDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Contents of application-context.xml:
<!-- main setup -->
<context:property-placeholder location="classpath*:**/*.properties"/>
<context:annotation-config/>
<context:component-scan base-package="nl.codebasesoftware.produx.domain" />
<context:component-scan base-package="nl.codebasesoftware.produx.service" />
<context:component-scan base-package="nl.codebasesoftware.produx.dao" />
<!-- Data and JPA setup -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${db.driverClassName}"
p:url="${db.url}" p:username="${db.username}" p:password="${db.password}"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
Contents of application-context-web.xml:
<mvc:annotation-driven />
<context:component-scan base-package="nl.codebasesoftware.produx.controller" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
Contents of webapps/META-INF/persistence.xml
<persistence-unit name="mysqlPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<!-- <property name="hibernate.hbm2ddl.auto" value="create-drop"/> -->
</properties>
</persistence-unit>
<!-- Needed to properly process #PersistenceContext which injects the entity manager -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
Contents of environment.properties:
db.url=jdbc:mysql://localhost:3306/yourDatabaseName
db.driverClassName=com.mysql.jdbc.Driver
db.username=yourUsername
db.password=yourPassword

cache database query in application server

I had webapps using spring jdbc template and now , want to improve performance of my application , so i want to cache result of some DATABASE QUERY in my Tomcat server.How i can achieve dis concept.
Thanks
Spring 3.1 has introduced a Caching Abstraction. You should be able to make use of this to cache the results of your DAO method calls.
The documentation is here and it was included in the Spring blog here.
I have it working, but Alex is correct, there are a few different ways to configure this, depending on what you want as your Caching backend.
For cache configuration, I've selected ehcache, as it's simple to configure, but has powerful features for configuring ttl/etc.
Configuration:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager"><ref local="ehcache"/></property>
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml"/>
</beans>
ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
<!-- http://ehcache.org/documentation/configuration.html -->
<!-- Also See org.springframework.cache.ehcache.EhCacheFactoryBean -->
<diskStore path="java.io.tmpdir"/>
<cache name="resourceBundle"
overflowToDisk="false"
eternal="false"
maxElementsInMemory="500"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"/>
</ehcache>
I had issues with running the ehcache 2.5 in my junit environment, due to caches with duplicate names running concurrently was not allowed, and they didn't seem to shut down right away, but here is my pom entry:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.4.7</version>
</dependency>
Finally, on your repository, do the following:
#Repository
public class someStore {
#PersistenceContext
EntityManager em;
//The value here needs to match the name of the cache configured in your ehcache xml. You can also use Spel expressions in your key
#Cachable(value = "resourceBundle", key = "#basename+':'+#locale.toString()")
public ResourceBundle getResourceBundle(final String basename, final Locale locale){
...
}
#CacheEvict(value = "resourceBundle", key = "#basename+':'+#locale.toString()")
public void revertResourceBundle(final String basename, final Locale locale){
...
}
}