Spring boot JPA ddl-auto update - sql-server

When i try to set ddl auto to update, every time I run the application, it shows that hibernate tries to create the tables again. I am trying to add another column in the database using the entity
#Column(name = "xref_reason", length = 20)
private String xRefReason;
Shouldn't it creates this column only that I added?
Here is the error.
Hibernate: create table tbcodetable (id bigint identity not null, codename varchar(255), codevalue varchar(255), desc1 varchar(255), desc2 varchar(255), primary key (id))2018-06-26 16:23:09.342 WARN 4284 --- [ost-startStop-1] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: There is already an object named 'tbcodetable' in the database.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:258) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1535) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:845) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:752) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7151) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2478) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:219) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:199) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.execute(SQLServerStatement.java:729) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-2.7.8.jar:na]
at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-2.7.8.jar:na]
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
... 119 common frames omitted
even the foreign keys has the same error.
application.yml
spring:
profiles:
active: dev
datasource:
url: jdbc:sqlserver://localhost;database=dbname
username: user
password: password
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
hikari:
minimum-idle: 1
maximum-pool-size: 10
pool-name: collectionPool
auto-commit: false
jpa:
show-sql: true
hibernate:
default_schema: dbo
ddl-auto: update
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

Related

"SQLSTATE[42S02]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server] Invalid 'users' object name

I migrated my MySQL database to SQL Server 2019.
I made the required configurations:
php.ini
extension=php_pdo_sqlsrv_80_ts_x64
extension=php_sqlsrv_80_ts_x64
.env
DB_CONNECTION=sqlsrv
DB_HOST=servername
DB_PORT=null
DB_DATABASE=dbname
DB_USERNAME=sa
DB_PASSWORD=password
The code below is working fine. O test this in web.php and i get db connect successfully and all (2) tables.
try {
DB::connection()->getPdo();
echo DB::connection()->getDatabaseName()." db connect successfully";
} catch (Exception $e) {
dd($e->getMessage());
}
$sql = DB::select("SELECT TOP (2) id, email, email_verified_at, password, remember_token, image, userable_id, userable_type, created_at, updated_at, deleted_at FROM soraeir.users", [1]);
die(print_r($sql));
Message when I try to login I get:
SQLSTATE[42S02]:
[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]
Invalid 'users' object name. (SQL: select top 1 * from [users] where [email] = admin and [users].[deleted_at] is null)"
I think eloquent must add an instance_name to all queries...I don't know how to proceed...?
Perhaps, instead of
select top 1 *
from [users]
where [email] = admin
and [users].[deleted_at] is null
We could use
select top 1 *
from [instance_name].[users]
where [email] = admin
and [users].[deleted_at] is null
I solved my problem
my problem was when I was doing the migration I misconfigured at the level of schema mapping with sql server migration assistant for mysql.
all my tables in sql server db was : mysql_db_name.table_name
Solution
Source Schema: mysql_db_name
Target Schema : sqlsrv_db_name.dbo
dbo is required
now all tables are as follows : dbo.table_name

Why do I get a 'select active warehouse' error in dbt when trying the table materialization, but not with the view materialization?

I've been working with dbt for a couple of months now, so still fairly new to it. When running a test model, I have no problems when using the view materialization:
{{ config(materialized='view') }}
select 1 as id
Resulting in:
15:30:25 | 1 of 1 START view model dbt.stg_CampaignTableTest.................... [RUN]
15:30:26 | 1 of 1 OK created view model dbt.stg_CampaignTableTest............... [SUCCESS 1 in 1.48s]
However, when I make the switch to a table materialization I get an error message about not having an active warehouse selected in Snowflake:
{{ config(materialized='table') }}
select 1 as id
Resulting in:
15:32:52 | 1 of 1 START table model dbt.stg_CampaignTableTest................... [RUN]
15:32:53 | 1 of 1 ERROR creating table model dbt.stg_CampaignTableTest.......... [ERROR in 1.22s]
Database Error in model stg_CampaignTableTest (models/test/stg_CampaignTableTest.sql)
000606 (57P03): No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command.
Of course, it's not possible to include a "use warehouse" statement within my test model as it is inserted into the compiled SQL at the wrong position:
{{ config(materialized='table') }}
use warehouse "AnalysisTeam_WH";
select 1 as id
Because it leads to:
2021-10-07T15:33:59.366279Z: On model.my_new_project.stg_CampaignTableTest: /* {"app": "dbt", "dbt_version": "0.21.0", "profile_name": "user", "target_name": "default", "node_id": "model.my_new_project.stg_CampaignTableTest"} */
create or replace transient table "AnalysisTeam"."dbt"."stg_CampaignTableTest" as
(
use warehouse "AnalysisTeam_WH";
2021-10-07T15:33:59.366342Z: Opening a new connection, currently in state closed
2021-10-07T15:34:00.163673Z: Snowflake query id: 019f7386-3200-ec67-0000-464100e189fa
2021-10-07T15:34:00.163803Z: Snowflake error: 001003 (42000): SQL compilation error:
syntax error line 4 at position 0 unexpected 'use'.
I appear to have the correct permissions with my Snowflake 'role' to create tables, views, etc., so I was at a loss to understand why changing from view to table would cause the model to fail. I suspect it could be related to Snowflake permissions rather than a dbt issue but I am not sure. Any ideas would be really appreciated!
Edit: I appeared to make a mistake with my screenshots so I have switched to code snippets which is hopefully clearer.
I would suggest checking two possibilities.
A. The active profile coniguration at "~/.dbt/profiles.yml" Snowflake Profile:
and search for 'warehouse:'
my-snowflake-db:
target: dev
outputs:
dev:
type: snowflake
account: [account id]
# User/password auth
user: [username]
password: [password]
role: [user role]
database: [database name]
warehouse: [warehouse name] <<<<<
schema: [dbt schema]
threads: [1 or more]
B. Default warehouse setting for user used for connection ALTER USER:
SHOW USERS;
ALTER USER user_name SET DEFAULT_WAREHOUSE = '<existing_warehouse_name>';
Make sure the Snowflake Role dbt is using has been granted access to the Snowflake Warehouse dbt is using.
show grants on warehouse 'xxxxxxxx'

liquibase.exception.DatabaseException: ERROR: relation "container" already exists

I'm working on an application with liquibase, spring-boot and hibernate.
The database used is PostgreSQL. In order to populate the DB at startup I configured a data.sql file in src/main/resources, containing some insert statements.
In addition, after the boot there is also liquibase trying to apply all the changesets, one of them being the creation of a table populated using the data.sql file. So I get the following non blocking error, when executing the mvn cmd to start the app:
2018-04-25 14:33:53.417 ERROR 11060 --- [neut-Executor-1] liquibase : classpath:config/liquibase/master.xml: config/liquibase/changelog/20180424154826_added_entity_Container.xml::20180424154826-1::jhipster: Change Set config/liquibase/changelog/20180424154826_added_entity_Container.xml::20180424154826-1::jhipster failed. Error: ERROR: relation "container" already exists [Failed SQL: CREATE TABLE public.container (id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(2000), container_type VARCHAR(255), created TIMESTAMP WITHOUT TIME ZONE, CONSTRAINT PK_CONTAINER PRIMARY KEY (id))]
2018-04-25 14:33:53.453 ERROR 11060 --- [neut-Executor-1] i.g.j.c.liquibase.AsyncSpringLiquibase : Liquibase could not start correctly, your database is NOT ready: Migration failed for change set config/liquibase/changelog/20180424154826_added_entity_Container.xml::20180424154826-1::jhipster:
Reason: liquibase.exception.DatabaseException: ERROR: relation "container" already exists [Failed SQL: CREATE TABLE public.container (id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(2000), container_type VARCHAR(255), created TIMESTAMP WITHOUT TIME ZONE, CONSTRAINT PK_CONTAINER PRIMARY KEY (id))]
liquibase.exception.MigrationFailedException: Migration failed for change set config/liquibase/changelog/20180424154826_added_entity_Container.xml::20180424154826-1::jhipster:
Reason: liquibase.exception.DatabaseException: ERROR: relation "container" already exists [Failed SQL: CREATE TABLE public.container (id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(2000), container_type VARCHAR(255), created TIMESTAMP WITHOUT TIME ZONE, CONSTRAINT PK_CONTAINER PRIMARY KEY (id))]
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:619)
at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:51)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:79)
at liquibase.Liquibase.update(Liquibase.java:214)
at liquibase.Liquibase.update(Liquibase.java:192)
at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:431)
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:388)
at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.initDb(AsyncSpringLiquibase.java:94)
at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.lambda$afterPropertiesSet$0(AsyncSpringLiquibase.java:77)
at io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor.lambda$createWrappedRunnable$1(ExceptionHandlingAsyncTaskExecutor.java:68)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: liquibase.exception.DatabaseException: ERROR: relation "container" already exists [Failed SQL: CREATE TABLE public.container (id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(2000), container_type VARCHAR(255), created TIMESTAMP WITHOUT TIME ZONE, CONSTRAINT PK_CONTAINER PRIMARY KEY (id))]
at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:309)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:55)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:113)
at liquibase.database.AbstractJdbcDatabase.execute(AbstractJdbcDatabase.java:1277)
at liquibase.database.AbstractJdbcDatabase.executeStatements(AbstractJdbcDatabase.java:1259)
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:582)
... 12 common frames omitted
Caused by: org.postgresql.util.PSQLException: ERROR: relation "container" already exists
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2155)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:288)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:430)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:356)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:303)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:289)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:266)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:262)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
at com.sun.proxy.$Proxy129.execute(Unknown Source)
at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:307)
... 17 common frames omitted
What I'm thinking is that the hibernate executing the data.sql gets executed just a moment before the liquibase migration process, so maybe there should be a way to avoid this exception. Is it possible to force the execution of hibernate importing data.sql to happen after liquibase migration?
you have to decide by which mechanism do you want to execute the changes. So you can use hibernate to create your tables and insert data or you can use liquibase to create you tables and data not both at the same time. What I was doing on previous projects was setting the hibenate to only validate mode spring.jpa.hibernate.ddl-auto=validateand using liquibase to create tables and insert data.

Spring boot, Hibernate - create-drop uses old schema

I have spring boot, spring data, hibernate and ms sql,
but with create-drop strategy, hibernate creates table based on older implementation of my #Entity class.
Entity class as so:
#Entity
public class User {
#Id
#GeneratedValue
private int id;
#Column(unique = true, nullable = false)
private String name;
#Column(nullable = false)
private String password;
#Column(nullable = false)
private String email;
#Column(nullable = false)
private boolean active = false;
#Column
private String activationUUID = UUID.randomUUID().toString();
//getters and setters
}
In application.properties, related config:
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.hibernate.ddl-auto=create-drop
But what I see in stdout, once I run my application:
2018-03-17 12:08:10.973 INFO 876 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.SQLServer2008Dialect
2018-03-17 12:08:11.473 INFO 876 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
Hibernate: drop table [user]
Hibernate: create table [user] ([id] int identity not null, [account_activationuuid] varchar(255), [account_active] bit not null, [email] varchar(255) not null, [name] varchar(255) not null, [password] varchar(255) not null, [registration_date] datetime2 not null, primary key ([id]))
Hibernate: alter table [user] add constraint UK_gj2fy3dcix7ph7k8684gka40c unique ([name])
2018-03-17 12:08:11.488 INFO 876 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
Note that I have deleted #Column registration date, renamed accountActivationUUID to activationUUID, and renamed accountActive to active.
Still, I see old schema in stdout, and it is even like this stored in database.
So, my questions:
1) Where does this old schema come from ?
2) Does hibernate have some schema cache ?
3) How to make it generate new schema every time - being exactly representation of #Entity classes in my code ?
4) Why does it say to use 2008 dialect in stdout, even though I have specified 2012 dialect in application.properties ?
I tried invalidating cache in intelj, restarting computer and database, to search for file with old schema definition on hard drive, but none of it worked.
Thanks for any response :)
I found the problem and managed to make it work.
Problem was in pom.xml, there were some duplicates and some non-existent dependencies, so the run was just falling to latest successful run.
That's how it was using old schema.

How to map two tables and not make any changes when mapping legacy database tables in Grails?

I'm new to Grails and mapping and I have something that looks like this.
I have two domain classes and I need to make a relationship between them, and when the relationship is done that no changes would be made to existing tables from my PostgreSQL database.
class Insurance{
Integer id
String osg_name
String osg_logo
String osg_email
String osg_link
static hasMany = [ insurancePackage: InsurancePackage]
static constraints = {
id(blank: false)
osg_name (blank: false, size: 0..155)
osg_logo (size: 0..155)
osg_email (blank: false, size: 0..100)
osg_link (size: 0..155)
}
static mapping = {
table name: "insurance", schema: "common"
version false
id generator :'identity', column :'osg_id', type:'integer'
}
}
class InsurancePackage{
Integer id
Integer osg_id
String osgp_comment
Integer tpo_id
String osgp_link
String osgp_label
//static belongsTo = Insurance
static belongsTo = [insurance: Insurance]
static constraints = {
id(blank: false)
osg_id (blank: false)
osgp_comment (blank: false, size: 0..500)
tpo_id (blank: false,)
osgp_link (blank: false, size: 0..155)
osgp_label (blank: false, size: 0..10)
}
static mapping = {
table name: "insurance_package", schema: 'common'
version false
id generator :'identity', column :'osgp_id', type:'integer'
}
}
This is the error that I'm getting
Error 2015-07-16 13:38:49,845 [localhost-startStop-1] ERROR hbm2ddl.SchemaUpdate - Unsuccessful: alter table revoco.insurance_package add column insurance_id int4 not null
| Error 2015-07-16 13:38:49,845 [localhost-startStop-1] ERROR hbm2ddl.SchemaUpdate - ERROR: column "insurance_id " contains null values
| Error 2015-07-16 13:38:49,845 [localhost-startStop-1] ERROR hbm2ddl.SchemaUpdate - Unsuccessful: alter table revoco.insurance_package add constraint FK684953517A89512C foreign key (insurance_id ) references revoco.insurance
| Error 2015-07-16 13:38:49,845 [localhost-startStop-1] ERROR hbm2ddl.SchemaUpdate - ERROR: column "insurance_id " referenced in foreign key constraint does not exist
So I cant connect the two tables and I'm getting the same error, for some reason Grails are trying to find insurance_id but that is not defined in classes and they are trying to alter my tables and I don't want that to happen.
You are created a new column in the insurance_package table that holds a foreign key to the insurance table. (hasMany and belongsTo --> one-to-many)
The problem here is that the column has a NOT NULL contraint by default but the table appears to have already data in it.
The question is now: What to do with the data already contained in the table. Grails wants to set the NOT NULL constraint but can't because there are already in there and because you have just created the column and the values are NULL
You have 3 options depending on your use case:
delete the values already contained in the table (maybe not wanted)
Go in your db management tool and set a foreign key for those rows and then restart the server. The error should disappear
set the constraint for your insurance reference (belongsTo) in your "InsurancePackage" object to be nullable:true

Resources