JPA/Hibernate can't create Entity called Order - java

I'm using Hibernate/JPA and have an #Entity object called Order, pointing at a MySQL database using Hibernate's dynamic table generation i.e. generate tables at runtime for entities. When Hibernate creates the tables, it creates tables for all of my entities except the Order entity. If I rename the Order entity to something else e.g. StoreOrder, the store_order table is created no problem.
Furthermore, if I do this but then annotate the StoreOrder object to specify that the table it should create is called 'order' using #Table (name="order"), the table is no longer created.
I realise that order is a reserved word but is this the reason that it can't create the table? It seems odd given that the Hibernate docs uses an example of an entity called Order.
It doesn't look like a MySQL problem as I can manually create a table called order directly on the database.
Here's the relevant Order entity object definition...
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Order extends PersistentEntity {
... rest of POJO def...
}
...and the corresponding Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="store" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>conf/jpa/persistence-query.xml</mapping-file>
<!-- Entities -->
...other entities...
<class>ie.wtp.store.model.Order</class>
<class>ie.wtp.store.model.OrderItem</class>
<!-- Hibernate properties -->
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/store"/>
<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.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.query.factory_class"
value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory"/>
<property name="hibernate.query.substitutions" value="true 1, false 0"/>
<property name="cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Any thoughts as to why this Order entity is not created but is created if I rename it to StoreOrder?
Cheers,
J :)

The ORDER word is a reserved keyword, you have to escape it.
In JPA 1.0, there is no standardized way and the Hibernate specific solution is to use backticks:
#Entity
#Table(name="`Order`")
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Order extends PersistentEntity {
... rest of POJO def...
}
JPA 2.0 standardized this and the syntax looks like this:
#Entity
#Table(name="\"Order\"")
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Order extends PersistentEntity {
... rest of POJO def...
}
References
Hibernate Core documentation
5.4. SQL quoted identifiers
JPA 2.0 specification
2.13 Naming of Database Objects

Probably because 'Order' is a keyword in SQL. When I encounter this I normally just put 'Tbl' on the end of my entity/table names to avoid the potential clash.

Related

multiple persistence unit eclipselink

I m using an osgi application with postgresql connection and a persistence.xml that containt some properties like
<persistence-unit name="postgres-name"
transaction-type="JTA">
<properties>
<!-- <property name="show_sql" value="true" /> -->
<!-- <property name="hibernate.format_sql" value="true" /> -->
<property name="eclipselink.logging.level" value="FINEST"/>
<property name="eclipselink.logging.level.sql" value="FINEST"/>
...many other properties...
</properties>
</persistence-unit>
And in another bundle i want to initialize a H2database with its own unitname, so i have declared a new persistence.xml with :
<persistence-unit name="h2-unitname"
transaction-type="RESOURCE_LOCAL">
<properties>
...many properties...
<property name="eclipselink.allow-zero-id" value="true"/>
...many other properties...
Problem is when i get EntityManager for postgres database, all work fine, next i get h2 EntityManager and work fine, but next time postgres EntityManager is used, i have an error :
Detail: key (id)=(0) already exist
Call: INSERT INTO TABLE(ID, TEST) VALUES (?, ?)
bind => [0, null]
I think my property eclipselink.allow-zero-id define in h2 unitname ovveride the postgres EntityManager...
In fact if i use always postgres database with 0 id, all wark fine, because sequence is call, but if i use one time the h2 EntityManager, entity with 0 id don't work anymore because of allow-zero-id.
How can i define separate property for each persistent unitname?
Ask me if you want to see more configuration
thanks by advance

Is there a way to map same hibernate entity to multiple tables in different schemes

This is the situation. I have a table called customer and this table is repeating among different schemes in the same database. so the problem is when i'm going to map this customer table with hibernate entity do i need to create multiple classes for specifying the schema or can i dynamically change the schema in the entity. I'm a newbie to this hibernate framework please help.
You need to have more persistence unit. And use entity manager created via entity manager factory which used proper persistence unit.
In persistence.xml
<persistence-unit name="pu1" transaction-type="RESOURCE_LOCAL">
<property name="hibernate.connection.url" value="jdbc:database://url1"/>
<property name="hibernate.connection.username" value="username"/>
<property name="hibernate.connection.password" value="pass"/>
...
</persistence-unit>
<persistence-unit name="pu2" transaction-type="RESOURCE_LOCAL">
<property name="hibernate.connection.url" value="jdbc:database://url12"/>
<property name="hibernate.connection.username" value="username"/>
<property name="hibernate.connection.password" value="pass"/>
...
</persistence-unit>
private static EntityManagerFactory emf1;
private static EntityManagerFactory emf2;
emf1 = Persistence.createEntityManagerFactory("pu1");
emf2 = Persistence.createEntityManagerFactory("pu2");
emf1.createEntityManager();//Will store to database defined in pu1
emf2.createEntityManager();//Will store to database defined in pu2

How to overwrite the table in JPA or Entity?

I have one java project. In that I use #Entity. In my project have some constraints. Tables should be created automatically. So I use JPa #Entity. what the problem is that, when ever the Program is restarting, the new table is created by the Entity. So my old data got losed. I need those type of data. Trap Entity should not overwrite my content in Database? How to solve it?
use <property name="hibernate.hbm2ddl.auto" value="update"/> in your persistence.xml . If you have not generate the schema then first use <property name="hibernate.hbm2ddl.auto" value="create"/> and the schema will be generated. Then use <property name="hibernate.hbm2ddl.auto" value="update"/> since now you have the schema.
In the persistence.xml file there should be a setting to turn off the auto generation of DLL. Here is an example of a persistence.xml file using hibernate where the hibernate.hbm2ddl.auto property has been set to validate, which will cause the tables not to be overwritten. If your relying on Hibernate to create your DDL you would not want to have this set the first time your run the application, it would be set after running once and successfully creating the DDL (Tables).
If this setting were set to create-drop the schema would recreate the tables each time the persistence context is created, causing all data to be lost. This property will be specific to your ORM vendor's implementation.
The best advice is to find the documentation for your vendor's specific setting and then choose the option which best fits your needs. This post does a good job of describing the possible values for the setting in Hibernate.
<persistence-unit name="toThought" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
</properties>
</persistence-unit>
In EclipseLink this property is:
<property name="eclipselink.ddl-generation" value="create-tables"/>

Exclude one class from creating a Table in hibernate

I have a persistence unit like this:
<persistence-unit name="persistence Unit"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.example.User</class>
<class>com.example.Team</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<!-- JTA stuff -->
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.BTMTransactionManagerLookup" />
</properties>
</persistence-unit>
When the server loads first time, this creates table for User and Team, but i dont want to create a table for Team. Is it possible?
Some settings in the persistence table maybe?
If table Team isn't changed (INSERT or UPDATE) by your application in any way, you could remove write permissions for it in your database system.
Exclude Team class from your persistance.xml Remove following line.
<class>com.example.Team</class>

Hibernate: Automatically creating/updating the db tables based on entity classes

I have the following entity class (in Groovy):
import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
#Entity
public class ServerNode {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id
String firstName
String lastName
}
and my persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<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>
</persistence>
and the script:
import javax.persistence.EntityManager
import javax.persistence.EntityManagerFactory
import javax.persistence.Persistence
import net.interaxia.icarus.data.models.ServerNode
def factory = Persistence.createEntityManagerFactory("NewPersistenceUnit")
def manager = factory.createEntityManager()
manager.getTransaction().begin()
manager.persist new ServerNode(firstName: "Test", lastName: "Server")
manager.getTransaction().commit()
the database Icarus exists, but currently has no tables. I would like Hibernate to automatically create and/or update the tables based on the entity classes. How would I accomplish this?
I don't know if leaving hibernate off the front makes a difference.
The reference suggests it should be hibernate.hbm2ddl.auto
A value of create will create your tables at sessionFactory creation, and leave them intact.
A value of create-drop will create your tables, and then drop them when you close the sessionFactory.
Perhaps you should set the javax.persistence.Table annotation explicitly?
You might try changing this line in your persistence.xml from
<property name="hbm2ddl.auto" value="create"/>
to:
<property name="hibernate.hbm2ddl.auto" value="update"/>
This is supposed to maintain the schema to follow any changes you make to the Model each time you run the app.
Got this from JavaRanch
Sometimes depending on how the configuration is set, the long form and the short form of the property tag can also make the difference.
e.g. if you have it like:
<property name="hibernate.hbm2ddl.auto" value="create"/>
try changing it to:
<property name="hibernate.hbm2ddl.auto">create</property>
In my case table was not created for the first time without last property listed below:
<properties>
<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-drop"/>
<!-- without below table was not created -->
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
</properties>
used Wildfly's in-memory H2 database
There is one very important detail, than can possibly stop your hibernate from generating tables (assuming You already have set the hibernate.hbm2ddl.auto). You will also need the #Table annotation!
#Entity
#Table(name = "test_entity")
public class TestEntity {
}
It has already helped in my case at least 3 times - still cannot remember it ;)
PS. Read the hibernate docs - in most cases You will probably not want to set hibernate.hbm2ddl.auto to create-drop, because it deletes Your tables after stopping the app.
TO CREATING TABLE AUTOMATIC , NO CONNECTION WITH ANNOTATIONS
FOR THAT WE NEED TO CHANGE "hibernate.cfg.xml" as like.
<property name="hbm2ddl.auto">update</property>
In applicationContext.xml file:
<bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- This makes /META-INF/persistence.xml is no longer necessary -->
<property name="packagesToScan" value="com.howtodoinjava.demo.model" />
<!-- JpaVendorAdapter implementation for Hibernate EntityManager.
Exposes Hibernate's persistence provider and EntityManager extension interface -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
In support to #thorinkor's answer I would extend my answer to use not only #Table (name = "table_name") annotation for entity, but also every child variable of entity class should be annotated with #Column(name = "col_name"). This results into seamless updation to the table on the go.
For those who are looking for a Java class based hibernate config, the rule applies in java based configurations also(NewHibernateUtil). Hope it helps someone else.

Categories

Resources