H2 database schema creation check - java

I have H2 database generated on the-fly using Hibernate & Spring for my test-cases.
I have few weird errors, and I would like to know exactly how the schema looks like in H2. how the tables defined, and how the columns.
How can I generate this report during run-time ?

If the schema is being deployed by Hibernate using hibernate.hbm2ddl.auto=true you could turn on trace logging for org.hibernate.tool.hbm2ddl. This would show you the DDL Hibernate is generating when it creates your schema.

You could run the SQL statement SCRIPT NODATA.
To see the SQL statements that are run against the database, append ;TRACE_LEVEL_FILE=2 to the database URL. This will write all SQL statements to the .trace.db file.

If you want to know what are the schemas getting generated on the fly. Simply add
<prop key="hibernate.show_sql">true</prop>
With this you'll be able to debug.

Related

Create a Hibernate schema not automatically, but with SQL script

In my project I use h2 in memory database, and I want it to be created not by Hibernate, but with by a SQL script. Here is my hibernate.properties
I made
hibernate.hbm2ddl.auto=none
none to disable autocreation of database, and added
hibernate.hbm2ddl.import_files=schema.sql,insert-users.sql
schema.sql contains SQL code to create schema, and then to insert-users.sql and it contains the initial data.
The project builds successfully, but when I try to hit database, I get
a Table <tablename> not found exception.
Since Hibernate won't do this for you unless you use create or create-drop hbm2ddl, there are other ways to achieve what you want.
Specialized tools
There are tools that are created specifically for this: Flyway, LiquiBase. These are often configured to be run when the app is deployed and allow you to version DB scheme. They are applicable not only for testing (and mainly - not for testing), but for production as well. They can ensure that the scheme on all your envs is the same. If you use these tools, then it's better to set hbm2ddl to validate.
Spring's support
Less widespread way is to use Spring's support for embedded DBs:
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
Data for testing
If the intention is to create data for testing (not scheme), then it's better to create entities and use your DAO/Repository layer to persist those in tests. This way you don't duplicate mechanisms of persisting data.
Two comments from the Hibernate documentation are relevant here:
This is useful for testing or demoing: by adding INSERT statements for example you can populate your database with a minimal set of data when it is deployed.
and
These statements are only executed if the schema is created ie if hibernate.hbm2ddl.auto is set to create or create-drop.
I'm not too sure that the import functionality will do what you want it to do.

Hibernate, load schema from file

In Hibernate, I can use hbm2dll tool to import data files after hibernate generates the schema from my model. This is fine, but I want to load the file with my database schema and make hibernate use that instead of generating one.
Let's say I have some database configured in my hibernate config
<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:."/>
Now before I run my test I want to load the db with some schema defined in my schema.sql file. And I don't want to use Spring, I know there is support for it there.
I know I could use hibernate.hbm2ddl to generate schema when SessionFactory is created but I'd rather want to load my manually defined schema. Something like <jdbc:embedded-database> from spring-jdbc.
Is there any support for that in Hibernate?
link1 and link2 might help you out.
Also you can set hibernate.hbm2ddl to none, and add your import.sql file in the classpath which will be executed at the server startup.

Why couldn't I see data committed to Postgres database from spring hibernate program?

I am trying to program using spring, JPAhibernate, and Postgres. There is no error running the program, and it successfully inserted data showing from client browser. However, Postgres database says relation "person" does not exist (My table name is "person"), which I think it means data is not committed to database. I tried
clean browser cache, and restart server. But program can still retrieve correct items. It looks like they are stored in the database.
set the hibernate.hbm2ddl.auto to be "validate" or "create-drop" or "update". But I can't see updated data in the database, even the table "person" doesn't exist.
Can anyone explain me why it's like this, or how can I see committed data in the database? Thank you.
The most common cause for this sort of thing is connecting to a different database, or a database of the same name on a different host/port, than you think you are. So you're not really modifying the same thing you are looking at.
<prop key="hibernate.hbm2ddl.auto">update</prop>
you can set hibernate.hbm2ddl.auto=update to update your database with changes to your model

Hibernate database name change gives MySQLSyntaxErrorException: Table doesn't exist

I used to have a database called database and everything was working well using hibernate and its models.
I removed <property name="hibernate.hbm2ddl.auto"> to avoid update or create as it's a production server, we want to do it manually.
We recently switched to database2 and so we switched the hibernate configuration file and all the hibernate XML models.
`<class name="com.api.models.database.MmApplications" table="mm_applications" catalog="database2">`
but it keeps looking for database event if we migrated the database, the models and the connexion.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'database.mm_applications' doesn't exist
Does someone can help me ?
UPDATE ----
Hibernate is connecting to the right database (database2), but there is a prefix as a prefix database. making the queries hitting the database instead of database2, and when I try to force the default_schema my queries become :
`... from database.database2.mm_applications ....`
Any idea?
My database is specified in the hibernate.connection.url property. Have you changed that also ? An example would be: jdbc:mysql://localhost/mydatabase
Also, instead of removing hibernate.hbm2ddl.auto then perhaps you should set its value to validate. That way hibernate will ensure that the datamodel matches the database schema.
I found the problem, It was an other application deployed on the same tomcat server using hibernate as well with another database (database) making a conflict with the new application ...
There is still something weird, by connecting to any database, hibernate will use the specified catalog in the hibernate models and so constructing the request using the catalog.table_name
Hope this help someone someday.

Autocreate Spring Entity "authorities" during testing

When trying unit tests with Spring Security & Hibernate, none of the security entities "user" or "authorities" are being autocreated. What I have done so far is to write an "user" bo that triggers generation of the appropiate table. However, I am stuck with the authorities:
(as advised by http://java.dzone.com/articles/getting-started-spring for postgresql)
CREATE TABLE authorities
(
username character varying(50) NOT NULL,
authority character varying(50) NOT NULL,
CONSTRAINT fk_authorities_users FOREIGN KEY (username)
REFERENCES users (username) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
Question: With Hibernate/JPA2, what is the appropiate syntax in order to create a BO representing this query?
Question: Actually, I do not want to create the entry using my own BO. Any better way to make Spring Security or Hibernate create all required tables during test run?
Thanks
Set the hibernate property hibernate.hbm2ddl.auto to update, for example. This should let hibernate automatically create (and update) the tables in needs.
<property name="hibernate.hbm2ddl.auto" value="update" />
Actually, I do not want to create the entry using my own BO. Any better way to make Spring Security or Hibernate create all required tables during test run?
If you don't plan to use Hibernate to interact with these tables, it makes indeed little sense to have Entities for them.
My suggestion would thus be to place the Spring Security tables creation script in an import.sql file and to put this file on the root of the class path and Hibernate will automatically execute it after schema export. See Spring/Hibernate testing: Inserting test data after DDL creation for details (just put your DDL statements on a single line).
Thanks, Pascal, this is just what I have been looking for, however, it does not work. I use maven and put import.sql into the resources dir root (content: CREATE TABLE justatest (aaa character varying(50) NOT NULL );). I also set . Running mvn test copies import.sql to target dir... but nothing happens. logback[debug] does not mention import.sql at all. Any idea where I am going wrong? (Hibernate V 3.5.1-Final)
I'm using this feature with Maven and I cannot reproduce your problem. I have hbm2ddl.auto set to create, my import.sql file is in src/test/resources and it gets executed as expected at the end of the schema export when running tests. Here is the log entry I get (using logback):
20:44:37.949 [main] INFO o.h.tool.hbm2ddl.SchemaExport - Executing import script: /import.sql

Categories