HIbernate creating database table - java

I am in the process of learning JPA - Hibernate.
I am following this article
In Dog.java it is mentioned as #Table(name = "dog").
In persistence.xml I have the following
<property name="hibernate.hbm2ddl.auto" value="create"/>
Does this creates table dog in database? I have not created table Dog in database. So in production environment this could be dangerous though. In such scenarios what should be ideal value for hibernate.hbm2ddl.auto?
Any suggestions?

it's dangerous in all senses, your application user should not have DDL permissions (alter table, create tables) your application user should only do DML (SELECT, INSERT,UPDATE,DELETE, etc)

Yes, it does create the new table every time that your app is deployed. Better to use:
<property name="hibernate.hbm2ddl.auto" value="validate"/>
if you already have data in place.
Here are the possible options:
validate: validate the schema, makes no changes to the database.
update: update the schema.
create: creates the schema, destroying previous data(!)
create-drop: drop the schema at the end of the session(!)

Do not set <property name="hibernate.hbm2ddl.auto" value="create"/> in production, because whenever you restart the server, all tables will be deleted and newly created again. You can make use of this property(hibernate feature) if you are migrating from one database to another.
If you want to set then set <property name="hibernate.hbm2ddl.auto" value="update"/> in development(not in production). This will update the schema if there are any changes you have made in pojo classes(annotations).
Also check : Hibernate: hbm2ddl.auto=update in production?
Hibernate hbm2ddl.auto possible values and what they do?

Set it to "none" in a production environment.

Related

How create the database through Hibernate

In my spring project, i am using Hibernate to export my entity classes to a previously created database. But this will require the final user knows how to create a database in the Database manager system (Currently I am using Postgresql).
Is there any way of, given only the machine where the postgresql is installed (and the username and password, which is provided when the application is runned the first time), the Hibernate create a new database in the server if it doesn't exist?
If your configuration looks like this
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://host:port/database</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.show_sql">false</property>
<property name="hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
Then the database will be created by Hibernate automatically.
Update:
Ok now I understand what you want. You want to start the Postgresql server with Hibernate. This is not possible. Hibernate does not do this.
You can do this with
Another script that starts with your application
A maven/ant target.
A build job
But the best solution is to use an in-memory database that does not need an external server (for example H2, or Java derby)
See also
Simulate CREATE DATABASE IF NOT EXISTS for PostgreSQL?
and
Postgres database create if not exists
Take a look of paramater hibernate.hbm2ddl.auto for your hibernate.cfg.xml file. I suggest you this link: Hibernate hbm2ddl.auto, possible values and what they do - any official explanation?
Run "CREATE DATABASE ..." (see http://www.postgresql.org/docs/9.0/static/sql-createdatabase.html) as a native SQL query ...
.createSQLQuery(" ... ").executeUpdate(); ...
Hibernate will - at least as far as I know - not create the database, only the tables in it.
I suppose you need to connect to postgresql via a second persistence unit/connection, because of the chicken-and-egg nature of this approach.

Hibernate entity manager looking for tables in different schemas

I am implementing jpa persistence using hiberante-entity manager in a java web project.
I have set following property in in persistence.xml.
<property name="hibernate.hbm2ddl.auto" value="update"/>
I have a schema for each user. For e.g i have a schema for user1 and one for user2.
If the table 'ABC' is present in user1 schema but not in user2 schema & I deploy the application and it uses user2 db credentials, i get the message 'user1.ABC' table found so the 'ABC' table is not created in user2 schema.
When i tried with following property in the persistence.xml file the table is created in the user2 schema.
<property name="hibernate.hbm2ddl.auto" value="create"/>
My question is
why hibernate is searching in another schema i.e user1 if the application is using user2 db credentials? and
I don't want to create the schema every time the server is started so how can i avoid using
the value 'create'.
EDIT: Below is my persistence.xml file
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="XXXXXX" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.axonframework.saga.repository.jpa.SagaEntry</class>
<class>org.axonframework.saga.repository.jpa.AssociationValueEntry</class>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Thanks in advance
I am also facing the same issue, and after digging a lot, get to know that the bug is related to the Mysql Connector.
After changing MySql Connector 6.0.5 to 5.1.28 It works fine for me.
I hope It can help you. Cheers
Has the same problem.
After set <property name="hibernate.default_schema" value="MY_SCHEMA"/> the problem has been solved.
Check if you are calling user1 and user2 in your Hibernate Sessionfactory.
If you want to handle several schemas properly then use multi-tenant per schema also if you want to update/create/migrate/handle columns/tables/schemas/databases then use flyway or liquibase
REFERENCES
Multitenancy https://vladmihalcea.com/hibernate-database-schema-multitenancy/
Flyway https://flywaydb.org
Liquibase https://www.liquibase.org
The Hibernate documentation is clear about this, you need to enable multi-tenant operations as described in this answer and this example.
Basically you have to declare multiple persistence units and have each point to a different schema. Each can then use different login credentials as well.
Hibernate documentation link
To summarise:
Define your persistence unit
Define your mapping files per persistence unit
When using JPA add the following:
3. Specifying tenant identifier from SessionFactory
4. Implement a MultiTenantConnectionProvider

In a Derby database, how are "username" and "table owner" related, and what is a simple way to set them?

I am using Derby to study Hibernate; I used to have it as an embedded database, but my ant jobs for filling it with data have trouble with that, so I'm switching to the network version.
Besides my Java/Hibernate program, I access the database with a Squirrel client. I just want a setup that is as simple as possible; I don't need even normal security, encryption, etc.
I've been using Squirrel to create the database, and a sql script to create tables. Then I run an ant job out of eclipse that puts data in the tables. The ant scripts would load one record when all I had was an embedded database, then say that the database was 'already open'; I switched to network server mode to allow the ant scripts to do more than one record.
The squirrel client refuses to connect unless there is a non-0-length username and password, so I put in admin/admin.
When I do this, it seems the database tables are organized under the username somehow. The 'Objects' window in squirrel shows the database name, ADMIN and some other things under that, TABLE and some other things under ADMIN, and then the tables I created under ADMIN. ADMIN does not appear in the Sql script, only in the username I use to create and log into the database, so I assume the tables are under ADMIN because that's my username; I don't know where else it would come from.
Whether I put "username=admin;password=admin" on the URL in my hibernate configuration or not, it says the (first) table I'm trying to add to doesn't exist.
So can someone please tell me what I have to do to have Squirrel and Java/Hibernate access the same tables as each other in a Derby database? I think a rudimentary understanding of the terms above -- username, schema, qualifiedName, and simpleName, as they are used by Squirrel and/or Derby, might do the trick.
Here's one of the table creations:
create table AdUser
( id bigint generated by default as identity (start with 1),
name varchar(255),
password varchar(255),
primary key (id),
unique(name)
);
and here's the hibernate config file:
<property name="hibernate.connection.url"> jdbc:derby://localhost:1527/C:/Users/rcook/workspaceGalileoLaptop/BHChap3/BegHibernateDB;username=admin;password=admin</property>
<property name="hibernate.connection.driver_class"> org.apache.derby.jdbc.ClientDriver40 </property>
<!-- <property name="hibernate.connection.username">sa</property> -->
<!-- <property name="hibernate.connection.password"></property> -->
<property name="hibernate.dialect"> org.hibernate.dialect.DerbyDialect </property>
<property name="hibernate.connection.pool_size">0</property>
<property name="hibernate.show_sql">false</property>
Let me repeat; this worked for one record in an embedded database, so I'm confident that the code for connecting, creating the mapped objects, committing, etc., all works; but I'm convinced I'm doing something wrong with the logins from the two access methods.
There is indeed an intermediate level of table organization inside each database called the "schema"; you can read more about Derby's schema implementation here: http://db.apache.org/derby/docs/10.9/ref/rrefschemaname.html
Note that the schema name defaults to your user name, but you can always explicitly specify the schema name in your queries:
select * from admin.aduser;
accesses a different table than does
select * from rcook.aduser;

How to debug JPA CriteriaBuilder queries

How can I debug a query built with JPA 2.0 CriteriaBuilder? Is there a way to print out the query that is being executed?
I am developing a web application using NetBeans, MySql, GlassFish. I would avoid starting MySql in debug mode, because it is used also for other applications. JPA provider is EclipseLink.
The same attributes in persistence.xml that also print the SQL that is generated from regular JPQL queries, should also print the SQL that is generated from Criteria queries.
E.g.
For Hibernate (used by e.g. JBoss AS) it's:
<property name="hibernate.show_sql" value="true" />
For EclipseLink (used by e.g. GlassFish) it's:
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
Also see: How to view the SQL queries issued by JPA?
If you are using Java and Spring, under resources, you can adjust your application.properties file and add the line below:
spring.jpa.show-sql=true

how to configure cache in hibernate with jboss? ? And test as well in kumud console?

Does any one know, how to configure cache for hibernate with jboss ?
My clear question is I am using JPA and Jboss. Every time I call JPA method its creating entity and binding query.
My persistence properties are
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
And I am creating entity manager the way shown below:
emf = Persistence.createEntityManagerFactory("pu");
em = emf.createEntityManager();
em = Persistence.createEntityManagerFactory("pu")
.createEntityManager();
Is there any nice way to manage entity manager resource insted create new every time or any property can set in persistance. Remember it's JPA.
The question is not clear, there are many second level cache providers for Hibernate and they are not application server specific.
To enable the second level cache, you need to set the following properties in Hibernate configuration file hibernate.cfg.xml:
<property name="hibernate.cache.use_second_level_cache">true</property>
And if you want to also enable query result caching:
<property name="hibernate.cache.use_query_cache">true</property>
Then, declare the name of a class that implements org.hibernate.cache.CacheProvider - a cache provider - under the hibernate.cache.provider_class property. For example, to use JBoss Cache 2:
<property name="hibernate.cache.provider_class">org.hibernate.cache.jbc2.JBossCacheRegionFactory</property>
Of course, the JAR for the provider must be added to the application classpath.
That's for the Hibernate side. Depending on the chosen cache provider, there might be additional configuration steps. But as I said, there are many second level cache providers: EHCache, JBoss Cache, Infinispan, Hazelcast, Coherence, GigaSpace, etc.

Categories

Resources