I'm writing a database synchronization tool for existing databases. One of the requirement is to validate the entities with the database schema. The program has to be aware of any database changes (like adding new columns to the database). I'm planning on using Hibernate for this project.
Is there anyway Hibernate can validate the difference between the entity and the table in the database?
Can Hibernate output SQL script so I can review the SQL script before running it to update the target database?
Yes hibernate can output the SQL in the logs.
You need to set the : - <property name="hibernate.show_sql" value="true"/>
but SQL generated by the server is little messy so you have to modify the column name as per your database table.
please have a look at the following XML of my project with the hibernate
<?xml version="1.0" encoding="UTF-8"?>
<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="communityPortalPersitenceUnit">
<class>com.googlecode.frameworksintegration.domain.Blog</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/conhint_prod" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="admin" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.zeroDateTimeBehavior" value="convertToNull"/>
<property name="hibernate.show_sql" value="true"/>
<!--Start :- connection pooling -->
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
<property name="hibernate.c3p0.max_size" value="100" />
<property name="hibernate.c3p0.min_size" value="0" />
<property name="hibernate.c3p0.acquire_increment" value="1" />
<property name="hibernate.c3p0.idle_test_period" value="300" />
<property name="hibernate.c3p0.max_statements" value="0" />
<property name="hibernate.c3p0.timeout" value="100" />
<!--End :- connection pooling -->
</properties>
</persistence-unit>
</persistence>
Related
I'm having troubles with "working with multiple databases" in Spring MVC - hibernate JPA
I have two databases called user_db and portal_db. I need to work with them in different jpa units.
here is my persistance.xml
<?xml version="1.0" encoding="UTF-8" ?>
<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_1_0.xsd" version="1.0">
<persistence-unit name="user_unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Package.Entity1</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost/user_db" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
<!--<property name="hibernate.hbm2ddl.auto" value="create-drop" />-->
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
<persistence-unit name="portal_unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Package.Entity2</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost/portal_db" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
<!--<property name="hibernate.hbm2ddl.auto" value="create-drop"/>-->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Problem is When I use create-drop and run my project, it creates both of my entites in both databases. Like table that should be only created by Package.Entity1 in user_unit, is also created in portal_unit.
And when I select,insert,update my entites, I set persistance unit in each of my individual DAO's.
for example, in Entity Dao's implementation I have:
EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit);
where persistenceUnit could be user_unit or portal_unit depending on implementation.
What changes should I make so it wont create same table in both databases?
Add <exclude-unlisted-classes>true</exclude-unlisted-classes> in both of yours persistence units OR use JPA 2.x
Add <exclude-unlisted-classes>true</exclude-unlisted-classes> in both your persistence units.
Please follow post below for detailed explanation:
Multiple persistance unit in persistence.xml creating tables in one another
I have a Java SE 1.7 standalone application.
It uses Hibernate 4.3 final and JPA 2.1 to retrieve thousands of rows from a db2 zos database.
I have a multiple tables tor retrieve related rows from.
All I am testing currently is retrieving the Parent Table rows then two related children table rows.
One child table has a one to one relationship the other has a One to Many relationship.
I can retrieve 2000+ rows from the main parent table OK, I hold these rows in a an ArrayList
Then I attempt to retrieve the children table rows using the Ids held in my array list.
This is when I generate the following exception:-
***** Out of Package Error Occurred (2015-01-14 15:55:29.935) *****
Concurrently open statements:
1. SQL string: SELECT .....
Number of statements: 1150
********************
My JPA entity classes do not have any Mappings between them e.g. #ManyTo or #OneTo
Heres my persistence.xml file
<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://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="persistence" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>table.class.One</class>
<class>table.class.Two</class>
<class>table.class.Three</class>
<properties>
<!-- Configuring JDBC properties -->
<property name="javax.persistence.jdbc.url"
value="jdbc:db2://host:port/LOCATION:retrieveMessagesFromServerOnGetMessage=true;emulateParameterMetaDataForZCalls=1;" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="pword" />
<property name="javax.persistence.jdbc.driver" value="com.ibm.db2.jcc.DB2Driver" />
<property name="hibernate.default_schema" value="schema" />
<property name="hibernate.connection.autocommit" value="false" />
<!-- Hibernate properties -->
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.DB2390Dialect" />
<property name="hibernate.connection.provider_class"
value="org.hibernate.connection.C3P0ConnectionProvider" />
<!-- Configuring Connection Pool -->
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="500" />
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.maxStatementsPerConnection"
value="10" />
<property name="hibernate.c3p0.idle_test_period" value="2000" />
<property name="hibernate.c3p0.testConnectionOnCheckout"
value="true" />
<property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces"
value="true" />
</properties>
</persistence-unit>
</persistence>
How can I get JPA and/or hibernate to "close" the open statements?
My peristance file is:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="jpa" transaction-type="RESOURCE_LOCAL">
<!-- provider -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>sau.se.migration.model.TGridStation</class>
<class>sau.se.domain.model.Graph</class>
<class>sau.se.domain.model.Role</class>
<class>sau.se.domain.model.StationPrincipale</class>
<class>sau.se.domain.model.StationSecondaire</class>
<class>sau.se.domain.model.User</class>
<class>sau.se.domain.model.Incident</class>
<class>sau.se.domain.model.Listes</class>
<class>sau.se.domain.model.Vip</class>
<class>sau.se.domain.model.Feeder</class>
<properties>
<!-- Classes persistantes -->
<!--<property name="hibernate.archive.autodetection" value="class, hbm"
/> -->
<!-- logs SQL -->
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="use_sql_comments" value="true" />
<!-- connexion JDBC -->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost/semap?zeroDateTimeBehavior=convertToNull" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding"
value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="123456789" />
<!-- Dialecte -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
</persistence>
And I am quiet sure that it is the only configuration file in my project because I tried to put wrong password and I got the expected error on connection.
I want to change semap db name to any other but in vain.
Is there any other configuration that I don't know?
UPDATE
The real problem is that my application is still working with semap db (the old one)
Hi all I have pretty strange problem let me first show my configuration etc. Here is persitance.xml:
<persistence-unit name="allegroTransactionPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/AllegroShop?UseUnicode=true&characterEncoding=utf8" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="topSecret" />
<property name="hibernate.connection.password" value="topSecret" />
<!-- <property name="hibernate.hbm2ddl.auto" value="create" /> -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="show_sql" value="true" />
<property name="hibernate.hbm2ddl.import_files" value="/SQL/payment_type.sql"/>
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
</properties>
</persistence-unit>
And here is method that I use to take data from my database:
#PersistenceContext( unitName = "allegroTransactionPersistenceUnit", type= PersistenceContextType.EXTENDED )
protected EntityManager em;
public List<AllegroTransactionImpl> readAllegroTransactionByCreateDate()
{
TypedQuery<AllegroTransactionImpl> query = this.em.createQuery( "SELECT allegroTransaction FROM com.springapp.mvc.classes.AllegroTransactionImpl allegroTransaction ORDER BY createDate DESC", AllegroTransactionImpl.class);
return query.getResultList();
}
And now the problem. Everything works great if I use hibernate to update / delete / add. but if I change some value directly in base (by SQL statement) hibernate don't refresh it question is why ?
Entity class
https://gist.github.com/spec8320/144100f049f54b73ad86
please make sure you had committed the change by SQL statement.
please check if you have enabled the 2nd level cache on AllegroTransactionImpl
Is it possible to make JPA use SSL for it's connections. I don't know very much about JPA, so I can't provide many details about what version and provider I'm using, but here is a stripped version of my persistence.xml file. Is there a property you can add that makes it use secure connections?
<?xml version="1.0" encoding="UTF-8" ?>
<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" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="MY_PERSISTENCE_UNIT" transaction-type="RESOURCE_LOCAL">
<!-- declare class entities here -->
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://URL_TO_SERVER" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.user" value="USERNAME" />
<property name="javax.persistence.jdbc.password" value="PASSWORD" />
<!-- Optimize database writes to use batching. -->
<property name="eclipselink.jdbc.batch-writing" value="JDBC" />
<!-- Avoids flush being triggered before every query execution. -->
<property name="eclipselink.persistence-context.flush-mode"
value="COMMIT" />
<!-- Configure connection pool. -->
<property name="eclipselink.jdbc.connections.initial" value="1" />
<property name="eclipselink.jdbc.connections.min" value="64" />
<property name="eclipselink.jdbc.connections.max" value="64" />
<!-- Timeout for connection. -->
<property name="eclipselink.jdbc.timeout" value="10" />
<!-- Configure cache size. -->
<property name="eclipselink.cache.size.default" value="1000" />
<!-- Configure database to be created on startup if not already existing.-->
<property name="eclipselink.ddl-generation" value="create-tables" />
<!-- Configure simple SQL logging for demonstration. -->
<property name="eclipselink.logging.level" value="FINE" />
<property name="eclipselink.logging.thread" value="false" />
<property name="eclipselink.logging.session" value="false" />
<property name="eclipselink.logging.exceptions" value="false" />
<property name="eclipselink.logging.timestamp" value="false" />
</properties>
</persistence-unit>
It is not anything JPA specific, just about adding arguments to JDBC connection String. Assuming that everything else is correctly set, then adding this should be enough:
?useSSL=true&requireSSL=true
If SSL connection in general is not working, then this page provides more information: MySQL 20.3.4.5. Connecting Securely Using SSL
I found this was useful in EclipseLink 2.5.0 to pass properties through to the JDBC driver:
<property name="eclipselink.jdbc.property.my_property_name" value="my_value" />
This is driver specific, but in your case it would be:
<property name="eclipselink.jdbc.property.useSSL" value="true" />
<property name="eclipselink.jdbc.property.requireSSL" value="true" />