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
Related
My project uses spring-data-jpa.
The company stipulates that the test environment and the generated environment database account have only read and write permissions.
I found that when ddl-auto is set to none, the database structure is also changed because there is no permission to cause the service to fail on start. How to set the ddl-auto attribute so that the program does not change the database nor do the check?
spring-data-jpa
document:https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-database-initialization
10.2. Initialize a Database Using Hibernate You can set spring.jpa.hibernate.ddl-auto explicitly and the standard Hibernate
property values are none, validate, update, create, and create-drop.
Spring Boot chooses a default value for you based on whether it thinks
your database is embedded. It defaults to create-drop if no schema
manager has been detected or none in all other cases. An embedded
database is detected by looking at the Connection type. hsqldb, h2,
and derby are embedded, and others are not. Be careful when switching
from in-memory to a ‘real’ database that you do not make assumptions
about the existence of the tables and data in the new platform. You
either have to set ddl-auto explicitly or use one of the other
mechanisms to initialize the database.
spring.jpa.hibernate.ddl-auto=none
The standard Hibernate property values are: create, update, create-drop, validate and none:
create – Hibernate first drops existing tables, then creates new tables.
update – the object model created based on the mappings (annotations or XML) is compared with the existing schema, and then Hibernate updates the schema according to the diff. It never deletes the existing tables or columns even if they are no more required by the application.
create-drop – similar to create, with the addition that Hibernate will drop the database after all operations are completed. Typically used for unit testing.
validate – Hibernate only validates whether the tables and columns exist, otherwise it throws an exception.
none – this value effectively turns off the DDL generation
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.
I used Hibernate to create an annotated class, and it worked fine for the first time I ran the application.
The problem is that I did a DROP TABLE using psql and now I want hibernate to re-create that table automatically again, based on my annotated class.
If I run the application again, the table is not created and I get an Exception saying that such table doesn't exist (when I try to access it).
What should I do to re-create that table, just as I was creating it for the first time?
you can try to set property
hibernate.hbm2ddl.auto = update
or generate ddl manually with
java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaExport options mapping_files
with this tool you can export ddl to a file and execute script manually or do it automatically (mapping_files is optional)
I am working on a project in which currently I have single persistence unit file as I have only one database schema there in my db. Now I need to separate that schema into two different schema. So I made two different ORM files and mapped it into the PU. Now when i build my EJB project its working fine but as soon as I build my WEB project it starts giving me compilation error.
So, is there any other way so that I can manage two different schema together??
Note that both the schema are related with foreign keys.
Please help me out.
If you are using Oracle and you have SCHEMA_1 and SCHEMA_2 and you can define synonyms:
As SCHEMA_2, grant the appropriate privileges to SCHEMA_1
Define synonyms in SCHEMA_1 for the tables in SCHEMA_2
Now in SCHEMA_1 you should be able to use SCHEMA_2 tables as if they were there
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.