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
Related
In a Spring Boot app, I am using Hibernate and 2 tables is created properly. However, I also need to insert data one of these tables and for this purpose I thought I should use Flyway.
Then I just added insert clauses to the Flyway and use the following parameters for Hibernate and Flyway in application.properties:v
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto= update # also tried none
spring.flyway.url=jdbc:mysql://localhost:3306
spring.flyway.schemas=demo-db
spring.flyway.user=root
spring.flyway.password=******
I have not used Flyway for initializing database and I am not sure if I can use Flyway with Hibernate as I mentioned above. Or, should I disable Hibernate table creation and create another migration script for table creation?
If you use flyway only for insert data don't do that. Try to use this:
With Hibernate:
In addition, a file named import.sql in the root of the classpath is executed on startup if Hibernate creates the schema from scratch (that is, if the ddl-auto property is set to create or create-drop).
With Basic SQL Scripts:
Spring Boot can automatically create the schema (DDL scripts) of your JDBC DataSource or R2DBC ConnectionFactory and initialize it (DML scripts). It loads SQL from the standard root classpath locations: schema.sql and data.sql
The issue here is that Hibernate does not automatically create tables. Additionally, if using Spring Boot, Flyway will run before the service using hibernate has started. As a result, your Flyway script are interacting with a table that does not exist.
The recommended way to do this is to use Flyway to manage both your database structure, your create tables etc, and static data. This will mean your database is versioned and provisioned ready for your service and hibernate can connect.
How i could define some schema and data to be inserted into db for
sql database in spring boot
Also could i do this for embedded databases
For example i am using two databases and i want to populate some data or define some schema and apply to different databases before application starts.
A file named import.sql in the root of the classpath is executed on startup if Hibernate creates the schema from scratch (that is, if the ddl-auto property is set to create or create-drop). This can be useful for demos and for testing if you are careful but is probably not something you want to be on the classpath in production. It is a Hibernate feature (and has nothing to do with Spring).
You can take a look in spring docs
I had a grails domain with a field named created Though now I've changed it to dateCreated. However, my database table still has the column named created so anytime I try to save a record grails complains saying Field 'created' doesn't have a default value even though I no longer have this field in my domain.
How does one get around this issue? Do I have to open my db and delete this column? In rails this is handled through migrations, what is the equivalent in grails?
If you just rename the domain field, you can specify column name in the mapping block, and not change it when you rename the related field. So, no DB changes will be needed at all.
class MyDomain {
Date dateCreated
static mapping = {
dateCreated column: 'created'
}
}
You must specified dbCreate = "update" in your DataSource.groovy.
If you are in development stage, you can change it to dbCreate = "create" to enable automatic schema refresh. Otherwise, in a production environment, you have to keep that configuration and alter the table manually.
You may refer to Grails DataSource doc, which also proposed some migration tools:
You can also remove the dbCreate setting completely, which is
recommended once your schema is relatively stable and definitely when
your application and database are deployed in production. Database
changes are then managed through proper migrations, either with SQL
scripts or a migration tool like Liquibase (the Database Migration
plugin uses Liquibase and is tightly integrated with Grails and GORM).
Coming from a mysql background, I am able to set the default schema name that I want to use for all my sql queries in the connection url. I now have an Oracle DB that I need to access. I am aware that I cannot specify the schema I want to use in the URL since the user is the schema name being used.
I realize that I can use a line of SQL code:
ALTER SESSION SET CURRENT_SCHEMA=default_schema
The project is using mybatis 2.3.5 as my SQL framework, but I am completely new to mybatis. Is there a simple way to configure mybatis to accomplish this? My application is a Spring 3 application, so I am using the Spring DataSourceTransactionManager to manage my transactions. I would presume that the manager must be made aware of this requirement to ensure that the command is sent whenever creating a new connection.
I've tried searching online, but most of the examples I find all have the schema names included within the sql queries in the SqlMaps, which I find to be bad practice.
In an ideal world, the schema name would be part of the URL such that I can make changes to the schema name for different environments (ex: dev, test, prod, etc) without touching the code (ie: only configured at the JNDI/application server level). I would be happy if I could use a Spring configuration value to set this as well as I could still use a JNDI lookup or a system environment property to retrieve the value.
Can anyone point me in the right direction?
Thanks,
Eric
As far as I know, there is no option in Oracle to change your URL in order to connect to a specific user schema.
1) mybatis: You may set your current schema to a deserved one before you start your operations. You can write your specification in a property file and set your method's arguments from that file. You do not need to change your code to change your schema in that case.
<update id="mySetSchemaMethod" parameterClass="String">
ALTER SESSION SET CURRENT_SCHEMA = ${schemaName}
</update>
2) trigger: If you are using this connection only for this particular java application, you can set a client event trigger so set your CURRENT_SCHEMA. This time, you need to change the trigger in order to manage test/prod changes.
CREATE OR REPLACE TRIGGER Set_Schema_On_Logon
AFTER LOGON
ON MY_SCHEMA
BEGIN
ALTER SESSION SET CURRENT_SCHEMA = MY_TEST_SCHEMA;
END;
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