Multi-schema DDL Foreign Key generation not working with Hibernate - java

i deploy oracle database and create 2 schema
core
msg
c_user table is in core and i wanna create m_message table in msg schema.
my application structure is:
Core-Project that is a independent dependency and includes in other projects and User.hbm.xml is there in it.
i add Core-Project into pom.xml of Message-Project. Message-Project has Message.hbm.xml.
i use hibernate 4 and my hibernate mapping file is somethings like below. when i start my application (Message-Project), i wanna to m_message created foreign key with c_user table that is in core schema but hibernate generated DDL is wrong. i think hibernate cannot set default_schema properties in User.hbm.xml that is not schema attribute!
Note. i don't wanna to add a schema attribute in User.hbm.xml because Core-Project added into more than 10 projects.
Message.hbm.xml in message-project
<class name="org.message.model.Message" table="m_message" schema="msg">
<many-to-one name="sender" column="sender_Id" entity-name="org.core.model.User" not-null="true" />
...
</class>
User.hbm.xml in core-project
<class name="org.core.model.User" table="c_user">
...
</class>
oracle-hibernate.properties
hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.url=jdbc:oracle:thin:#localhost:1521:HRM
hibernate.connection.username=msg
hibernate.connection.password=msg
hibernate.connection.internal_logon=normal
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.hbm2ddl_auto=update
hibernate.default_schema=core
hibernate XML configuration file
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource_" ref="dataSource_" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.default_schema"> ${hibernate.default_schema}</prop>
...
</props>
</property>
</bean>
hibernate generated DDL for foreign key in something like below:
alter table msg.m_message add constraint FK_filpe81gwdf3f6oqn54d5ybh3
foreign key (sender_Id) references msg.c_user
why msg.c_user? why hibernate cannot set default_schema for tables that haven't schema attribute?
i think the order of using default_schema for generate foreign key is :
1) using schema of User.hbm.xml and then if not exists
2) using schema of Message.hbm.xml and then if not exists
3) using the default_schema of oracle-hibernate.properties
how can i change this order? thanks a lot...

Most likely this is a bug. However, even if it is, it will not be fixed in Hibernate 4.
If you can replicate it with Hibernate 5.2, then you should open a new Jira issue, and the issue will be fixed.
However, relying on the HBM2DDL for your production database is much more of an issue. HBM2DDL is good for testing and prototyping, not for production environments. You should use Flyway to manage your database schema.

Related

How can I generate entities with IntelliJ without having a session factory?

I am using our internal libraries for generating a session factory. This means I don't have an xml file with Hibernate configuration; information like that are read from a configuration file in the container that my application is deployed in. I also don't create a new instance of SessionFactory anywhere in my code; I add a bundle that does that for me.
However, when I try to generate entities with IntelliJ, I get an error saying:
JPA annotation mappings require at least one Session Factory
Considering that I don't have a configuration file, and I don't construct the SessionFactory myself, is there a way to generate annotations?
You can generate entities using Database connection.
Go View->Tool Windows->Database click + to add new Data Source.
Go to "Project structure" (alt+ctrl+shift+s)
In "Project settings" select "Modules"
Press + and add the JPA/Hibernate facet in your module.
Go View->Tool Windows->Persistance, RB->Genrate Persisting Mapping->By Database Schema. And choose data source and package where generate.
I'm using spring data JPA and had a similar problem. To work around it, I created a temporary class as below and let IntelliJ create a hibernate.cfg.xml (hit the green + next to "Add to Session Factory"), both of which I deleted once I'd run the mapping. A bit of an annoying workaround, but much quicker than mapping everything manually. Hope this helps.
#Component
public class IMADEANENTITYMANAGEROK/*!?!?!*/ {
#Autowired
HibernateJpaSessionFactoryBean hibernateJpaSessionFactoryBean;
SessionFactory sessionFactory;
public IMADEANENTITYMANAGEROK()
{
sessionFactory = hibernateJpaSessionFactoryBean.getObject();
}
}
For Spring Data JPA, add the hibernate.cfg.xml under /resources.
E.g. for postgresql:
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:postgresql://localhost:5432/db_name</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.password"></property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
</session-factory>
</hibernate-configuration>
Set your own db url, username, password. Click browse right of "Add to Session Factory" to point to above hibernate.cfg.xml. Then the POJOs will be generated without error "JPA annotation mappings require at least one Session Factory".
After the generation, delete or rename the file hibernate.cfg.xml to hibernate.cfg.xml.bak incase you use it again.

Hibernate Mapping Changes not taking effect

I have a project using Hibernate and external XML mapping files. I switched from MySQL to Oracle. Some of my fields have the name 'date', which is okay in MySQL but not in
Oracle. It does not like
<property name="date" column="date" type="string" />
so I changed it to
<property name="sdate" column="sdate" type="string" />
When I re-rerun the code to generate the schema, it is still following the old version of the mapping file and not taking into account the new changes. I have even created a similar but different xml file and pointed my Hibernate config to this new file and it has the same problem.
Does anyone know why it could be following the old version of my mapping file and refusing to follow my updates?

Hibernate 3.2.5 with Play Framework 1.2.5

I am trying to use Hibernate 3.2.5 with Play framework 1.2.5
In Hibernate I am having two files:
1) cfg.xml file (containing the db config details along with some additional properties
2) hbm.xml file (containing the mapping between the java bean and the db table
For getting connected to the oracle 10g db, I am providing the db details in the application.config files like this and the connection is successful also when I start the server:
db.url=jdbc:oracle:thin:#localhost:1521/orcl
db.driver=oracle.jdbc.OracleDriver
db.user=system
db.pass=tiger
I want to know Where will I place the hbm.xml file (for mapping details) and the cfg.xml file for the remaining properties other than db connecion details?
Please let me know about this.
Regards,
Starting from the root directory of your application:
the hibernate.cfg.xml must be placed inside the app directory
the mapping files (the hbm files) where your models classes are defined, usually inside the app/models/ directory
Inside your hibernate.cfg.xml the mapping attributes should be something like:
<mapping class="models.yourHmbFile1"/>
<mapping class="models.yourHmbFile2"/>
Btw, I find easy to use the hibernate annotations instead of the hbm - xml mapping. Easier to write and to mantain.
If you prefer to annotate your model classes, you can delete the hbm files and directly map your annotated classes in your hibernate.cfg.xml.
In the application.conf you've to specify the data you have already added:
db.url=jdbc:oracle:thin:#localhost:1521/orcl
db.driver=oracle.jdbc.OracleDriver
db.user=system
db.pass=tiger
Also in the hibernate.cfg.xml you need to specify the connection data:
<property name="hibernate.dialect">...</property>
<property name="hibernate.connection.driver_class">...</property>
<property name="hibernate.connection.url">...</property>
<property name="hibernate.connection.username">...</property>
<property name="hibernate.connection.password">...</property>

Hibernate mapping locations specifying?

I am using spring and hibernate. I have mapping locations specified as:
My folder structure is as follows:
src/main/resources
.
...hibernate
.
.....hibernate2
<property name="mappingLocations" value="classpath:hibernate/*.hbm.xml" />
above property is looking into only hibernate folder and is not looking into subfoders. how can i force to find hbm files in sub folders as well?
Insert a wildcard * as below
<property name="mappingLocations" value="classpath*:hibernate/**/*.hbm.xml" />

hibernate generation for dynamic map

I am trying to generate hbm.xml files to support the dynamic map mode of Hibernate. When I run hbm2hbmxml my classes are generated with the name attribute instead of the entity-name attribute. When I try to use dynamic map, Hibernate fails to load data from the DB because it cannot find the class. I can manually change the it from name to entity-name and it works.
The actual output is:
<hibernate-mapping>
<class name="MyEntity" table="MyEntity" schema="dbo" catalog="MyDB">
...
</class>
</hibernate-mapping>
The necessary output should be:
<hibernate-mapping>
<class entity-name="MyEntity" table="MyEntity" schema="dbo" catalog="MyDB">
...
</class>
</hibernate-mapping>
My hibernate.properties file contains:
hibernate.default_entity_mode=dynamic-map
I am running hbm2hbmxml using hibernate3-maven-plugin version 2.2.
I would like some help configuring the hbm2hbmxml plugin such that it generates my classes with the entity-name attribute.
Thanks for the help.

Categories