I am currently trying to set the Storage Engine for a table, because from case to case MyISAM and InnoDB should be used. Unfortunately I did not find a way to set this in Hibernate, and I do not want to create each table by hand. My prefered way would be to anotate it in the Java-POJO, but I couldn't find a way to do so.
I've found Hibernate: what's the difference between MySQLDialect and MySQLInnoDBDialect?, which tells me that setting the Dialect to org.hibernate.dialect.MySQLMyISAMDialect would help (it says this for the InnoDB-Dialect, but it seems like one could choose the default dialect with this), but this method has two shortcommings: First, the dialect is chosen for all tables, and second, it creates a query like CREATE TABLE xy(..) type=MyISAM but the query would be correct with engine=MyISAM.
Also Hibernate mysql innodb says that there are defaults, and that I can overwrite them when creating tables, but not how - does somebody know how to do this?
Instead of org.hibernate.dialect.MySQLMyISAMDialect or org.hibernate.dialect.MySQLInnoDBDialect, you should use org.hibernate.dialect.MySQL5MyISAMDialect or org.hibernate.dialect.MySQL5InnoDBDialect.
This way, it creates the table using engine=MyISAM or engine=InnoDB.
But this configuration is global and if you really have a reason to configure it for a single table, you could try:
Hibernate import SQL (hibernate.hbm2ddl.import_files). Add the path to a SQL file which contains the alter table into it.
Related
Is there any way to change the column property from unique=true to unique=false without dropping the table?
Now I am stuck in the situation where tables has been created earlier and these table are containing data too. When I changed unique=true to unique=false it doesn't making any changes in table.
You can easily do this thing in the database. Suppose I have a table Person with Person_name having a unique constraint.
ALTER TABLE Person
DROP INDEX Person_name;
or
ALTER TABLE Persons
DROP CONSTRAINT Person_name;
If you try to achieve the same thing using hibernate, hibernate will try to drop and create the table again, which you do not want to happen.
Hmm... I don't know if you can allow yourself on database drop but you can try in your application properties file use:
spring.jpa.hibernate.ddl-auto=update
or
spring.jpa.hibernate.ddl-auto=create-drop
For more info:
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
Also if you know that you will have a lot of changes in database schema and you want to make it easy to work you should get familiar with
https://www.liquibase.org/
Hibernate won't update to implement constraints on the table because there is a possibility of having an error as the existing table might have inconsistencies.
I am auditing a Java object using Hibernate Envers annotations, but initial object creation occurs directly in the database using Pentaho (ETL).
I want to create the object using ETL and add a table entry to the Envers generated object_AUD and REVINFO tables.
I have been trying to find the generation strategy for the REV column from the REVINFO table, but I must be looking in the wrong places. Would someone help me find an effective generation strategy so I can manually insert records into the audited tables without causing possible collisions or weird behavior in the future?
What you seek is going to depend on whether or not you are configuring your application to take the default for org.hibernate.envers.use_revision_entity_with_native_id.
The default value (true) tells Envers to ask Hibernate to create the REVINFO table using a native-based primary key which will either be IDENTITY or SEQUENCE depending upon your database platform. If you look at the table definition for REVINFO in your database, you should be able to deduce this information.
If this property is configured using false, Envers will construct its own sequence metadata and provide that to Hibernate. The sequence is called REVISION_NUMBER and is stored in a table called REVISION_GENERATOR. The sequence is initialized to 1 and incremented by 1 as the default.
I read the discussion about using hbm2ddl.auto=update in order to auto-update changes to the database schema.
The thread is from 2008 and I do not know how secure it is to use the auto-update mode today.
We are running a small JavaEE on a Glassfish with Hibernate 4.3.11 and PostgreSQL. We plan to use continious integration with Jenkins.
Is it useful to work with hbm2ddl.auto=update enabled? Or is it better to use an easy alternative to update/check the updates maybe manually?
I know it is hard to give a blanket statement.
You should not use hbm2ddl.auto=update to update production databases.
Few reasons:
Hibernate will only INSERT missing columns and not modify existing columns. Therefore, if you rename a property (Client to Customer), Hibernate will create a new column Customer, leaving the column Client untouched. You will need to manually "move" the data there and remove the orphan column.
Hibernate will not remove constraints on no longer mapped columns. Thus, if your Client column was NOT NULL, any insert query to that table will now fail in the first place, because Hibernate won't provide any data for the orphan column (Which still has it's NOT NULL constraint) anymore.
Hibernate will not touch data types of existing columns. So, if you change a property type from String to Date - Hibernate will leave the column definition as varchar.
Hibernate does not remove columns of which you deleted the property, leading to data-polution and worst-case (The constraints remain in place) to no longer working applications.
If you create additiional constriants on existing columns - hibernate will not create them, because the column already existed before. (You might miss important contraints on the production db you added on existing columns)
So, perform your updates on your own is safer. If you have to take into account what hibernate is doing and what not - you'd better do it on your own from the scratch.
Our current database (MySQL) already has Indexes for its foreign keys since these use InnoDB, which (afaik) automatically generates IndexTables for foreign keys. Hibernate wasnt used to create these tables. So my question is: Is MySQL using Indexes for their foreign keys automatically, when I use Hibernate to fetch Data from its tables? Or do I have to configure Hibernate to use these Indexes?
Thank you,
ymene
Yes, the query optimizer decides to use or not to use an index. Use EXPLAIN on your SELECT statements to see what it uses. There is no difference in a query created by Hibernate or a hardcoded query.
Is MySQL using Indexes for their foreign keys automatically, when I use Hibernate to fetch Data from its tables? Or do I have to configure Hibernate to use these Indexes?
There is nothing to configure in Hibernate to make the SQL backend use indices for joins. Let Hibernate perform its queries and if the optimizer decides that using an index is appropriate, it will use it.
PS: I'm not talking about Index Hints syntax here, see HHH-2736 - support for native/SQL query hints in HQL/Criteria (Oracle SELECT hints for example), this is something different.
There is a UNIQUE database constraint on an index which doesn't allow more than one record having identical columns.
There is a piece of code, managed by Hibernate (v2.1.8), doing two DAO
getHibernateTemplate().save( theObject )
calls which results two records entered into the table mentioned above.
If this code is executed without transactions, it results INSERT, UPDATE, then another INSERT and another UPDATE SQL statements and works fine. Apparently, the sequence is to insert the record containing DB NULL first, and then update it with the proper data.
If this code is executed under Spring (v2.0.5) wrapped in a single Spring transaction, it results two INSERTS, followed by immediate exception due to UNIQUE constraint mentioned above.
This problem only manifests itself on MS SQL due to its incompatibility with ANSI SQL. It works fine on MySQL and Oracle. Unfortunately, our solution is cross-platform and must support all databases.
Having this stack of technologies, what would be your preferred workaround for given problem?
You could try flushing the hibernate session in between the two saves. This may force Hibernate to perform the first update before the second insert.
Also, when you say that hibernate is inserting NULL with the insert, do you mean every column is NULL, or just the ID column?
I have no experience in Hibernate, so I don't know if you are free to change the DB at your will or if Hibernate requires a specific DB structure you cannot change.
If you can make changes then you can use this workaround in MSSQL tu emulate the ANSI behaviour :
drop the unique index/constraint
define a calc field like this:
alter table MyTable Add MyCalcField as
case when MyUniqueField is NULL
then cast(Myprimarykey as MyUniqueFieldType)
else MyUniqueField end
add the unique constraint on this new field you created.
Naturally this applies if MyUniqueField is not the primary key! :)
You can find more details in this article at databasejournal.com