Hibernate does not create my tables - java

I'm having a weird problem using Spring and Hibernate. I started using Hibernate using this in hibernate.cfg.xml:
<property name="hbm2ddl.auto">create</property>
It worked fine, and Hibernate successfully created the tables needed in the database.
Now I'm using Spring and my bean used for hibernate in applicationContext.xml looks like this:
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="mappingResources">
<list>
<value>domain/Entity.hbm.xml</value>
<value>domain/Service.hbm.xml</value>
<value>domain/User.hbm.xml</value>
<value>domain/Arcos.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2dll.auto">create</prop>
</props>
</property>
</bean>
I had to drop the tables created by Hibernate at some point but Spring doesn't create them. I tried with create-drop instead of create (just in case someone asks). My DB Schema changed since I used Hibernate and I'm using a lot of getBeans("..."); in my code so it kind of bother me to reuse my Hibernate-only version just to create the tables. I also could create the table by hand, but what would be the point of using these frameworks?
I'm sure I'm doing something wrong somewhere, but I cannot find it. The console prompt an error saying there is no table named "the name of the table", so it connects to the DB successfully.
Thanks for your time :)

hibernate.hbm2dll.auto --> hibernate.hbm2ddl.auto
DLL = Dynamic Link Library
DDL = Data Definition Language

There's a typo in your code
<prop key="hibernate.hbm2ddl.auto">create</prop>
in the solution

Related

configure hibernate to map entities automaticly

I use hibernate ORM in my project.
Now I map entities like this :
<mapping class="entities.User"/>
but I have to do this for each entity I create - is there anything I can put in the hibernate configuration to make it scan itself for annotated entities in certain package?
thank you
You can place all your java entities in a JAR file and then provide the path of the JAR file in hibernate configuration file like this:
<mapping jar="path_to_your_jar_file"/>
Update:
This is helpful only if you have hbm.xml files for mapping instead of having annotations on your classes. These mapping files should be part of the JAR file.
Look at this link for addJar method of Configuration class.
Using spring can help you get the package scanned. See the config below
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan">
<list>
<value>com.tds.hibernate.entities</value>
</list>
</property>
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
</bean>

Prevent Hibernate schema changes

I am new to Hibernate and am having some issue with its configuration. I am trying to setup a read-only connection to a preexisting Oracle database. I do not want Hibernate to execute any DML/DDL and alter the database schema, yet every time I try deploying my project, this is the message I see:
INFO: updating schema
SEVERE: Unsuccessful: create table WILLOEM.SAMPLE_INFO (SAMPLE_ID varchar2(255) not null, CELL_LINE varchar2(255), STUDY_ID varchar2(255), primary key (SAMPLE_ID))
SEVERE: ORA-00955: name is already used by an existing object
No damage is being done here, since the table creation failed, but I don't want to create a situation where data can be lost. How can I configure Hibernate to act in a read-only manner? Can I prevent statement execution completely, without adding a new Oracle user that lacks the privileges?
Here is my current Hibernate configuration:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>oracle.jdbc.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:#source.db.somewhere.com:1524:WILLOEM</value></property>
<property name="username"><value>username</value></property>
<property name="password"><value>password</value></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="packagesToScan" value="com.willoem.project.hibernate" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
you could change
<prop key="hibernate.hbm2ddl.auto">update</prop>
to
<prop key="hibernate.hbm2ddl.auto">validate</prop>
this validates the schema, but it will not make any no changes to it.

Insert into database after spring hibernate sessionfactory is created

I want to insert some data in a table of database after the SessionFactory of spring hibernate has been created.
I have a CUSTOMER table and I want to insert a particular Customer into this table if the Customer doesn't exist.
This is the configuration of SessionFactory:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagesToScan" value="com.edfx.adb.persist.entity" />
<property name="entityInterceptor" ref="entityInterceptor" />
</bean>
I know that there is an option hibernate.hbm2ddl.import_files from which we can mention a sql file and the query will be executed at the time of SessionFactory initialization. But I don't want to follow this way.
Also I have found that we can use ServletContextListener for this kind of purpose, but I am not sure this is a good way to achieve what I want. Because what I understand is the listener will be initialized after deployment of war file, when the first user hit the application. So if I have a Scheduler which operates of the Customer and if the Scheduler get executed before any user hit the app, then the Scheduler wouldn't find that need-to-be-insert data.
Any pointer would be very helpful to me.
You can extend org.springframework.orm.hibernate4.LocalSessionFactoryBean and override buildSessionFactory() method to according to your requirement.

Spring SessionFactory creation domain objects auto scanning

In my spring dao configuration xml I currently have to manually list out the domain classes names. Is there any way to automate this to eliminate the need to manually list out a domain class whenever a new one is created?
To give a better idea of what I want to do this, using something similar to component-scan or such
Current code
<bean id="daoSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="applicationDataSource" />
<property name="annotatedClasses">
<list>
<value>com.greenwhich.application.domain.Driver</value>
<value>com.greenwhich.application.domain.DriverRealTimeCurrentLocation</value>
<value>com.greenwhich.application.domain.Journey</value>
<value>com.greenwhich.application.domain.Customer</value>
<value>com.greenwhich.application.domain.SystemConstants</value>
<value>com.greenwhich.application.domain.DriverRequest</value>
<value>com.greenwhich.application.domain.Account</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
All I require that the values under the "annotatedClasses" property is automatically detected
Is there any way to implement this? So far I have tried inserting a component-scan inside of the "annotatedClasses" property searching for the "Entity" annotation which did not work
Any help is greatly appreciated
You should be able to replace the annotatedClasses property with:
<property name="packagesToScan" value="com.greenwhich.application.domain" />
as part of your session factory configuration.

No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

What is this error about? "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here".
My spring config file looks something like this.
<bean id="jndiDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/devDS</value>
</property>
</bean>
<bean id="stsaDBFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="jndiDataSource" />
<property name="annotatedClasses">
<list>
<value>xx.yy.zz.User</value>
<value>xx.yy.UserResponse</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbmddl.auto">create</prop>
</props>
</property>
</bean>
<!-- ################################### Aspects ################################################## -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="stsaDBFactory" />
</property>
</bean>
All the DAO test passes when i test them outside of the container using junit. When I deploy it in jBoss as a portal app,I get this exception. Also it works fine if i remove the portal specific configuration and make it a simple web app and deploy it on jboss.Any idea?
You have defined a TransactionManager in your spring config but you are trying to execute a hibernate query in a method that is not transactional. Try adding #Transactional to your method or class.
I got around this problem by specifying the current_session_context_class in hibernate config to be "thread", as per the simple configuration shown in the hibernate configuration documentation.
But it recommends that its not safe for production usage.
Trying to add the following in your hibernate config should also help:
<property name="current_session_context_class">org.hibernate.context.ThreadLocalSessionContext</property>
Check out http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/architecture.html#architecture-current-session for more details.

Categories

Resources