how do i create table in mysql cluster using hibernate - java

I am using the hibernate with spring boot and table created in given database but not in another database like 10.10.1.350 is management node and 10.10.1.348 and 10.10.1.349 are child db. when we create table using query directly in 348 then table auto created in 349. But we are using the hibernate then table created in 348 but not auto create in 349.
Properties like:-
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://10.10.1.348:3306/test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=abc#1234
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
Pojo Class-
#Entity
#Table(name = "test")
#Getter
#Setter
public class Test {
#Id
#Column(name = "tst_id")
private Long tstId;
#Column(name = "tst_nm")
private String tstNm;
}
pom.xml for mysql dependency-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

Hibernate docs says:
Although Hibernate provides the update option for the hibernate.hbm2ddl.auto configuration property, this feature is not suitable for a production environment.
Just use Flyway or Liquibase for DB migrations. Spring boot integrates with both of them.

Related

Hibernate generate table in Postgre from SpringBoot MultiModuleProject

I have created a SpringBoot multi module project.
You can find the basic projectstructure here.
Now I'm trying to generate tables using Hibernate in the model-module.
Prerequisites:
database in docker environment:
docker run --name postgres -e POSTGRES_PASSWORD=user -e POSTGRES_USER=user -e POSTGRES_DB=postgres -p 5432:5432 -d postgres
model/pom.xml:
<project ...>
...
<dependencies>
<!--general-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--persistence-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>
</project>
model/src/main/resources/application-model.properties:
# spring datasource
spring.database.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=user
spring.datasource.password=user
# hibernate
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto = update
model/src/main/java/model/ModelConfig.java:
...
#SpringBootApplication
#EntityScan("com.test.model.*")
#PropertySource("classpath:application-model.properties")
public class ModelConfig {
}
model/src/main/java/model/MyEntity.java:
...
#Entity
#Data
public class MyEntity {
#Id
#GeneratedValue
private long id;
#Column
private String text;
}
web/src/main/java/web/WebConfig.java:
...
#Configuration
#ComponentScan("com.test.*")
public class WebConfig {
}
WebConfig is a configurationclass which right next to the WebApplication.java which has the main-function of the application.
So the #ComponentScan("com.test.*") in WebConfig should scan in com.test.model as well and find the ModelConfig bean, which in fact is the case:
taken from Intellij
In ModelConfig the annotation #EntityScan("com.test.model.*") should search for entities in com.test.model.*, which is the case for MyEntity.java.
Error:
Actually there is no error, #mvn clean install runs and builds everything and I can run the application without getting any error messages as you can see in the output.
But there is no table generated.
Expectations:
I expect this setup to generate a table called <my_entity>, with a id-field with autogeneration and a field called text with varchar(255), which are the defaults of #GeneratedValue and #Column in MyEntity.java.
Thanks in advance.

Google Cloud postgres instance not able to connect to spring boot app

I am using postgresSQL instance on google cloud platform in spring boot app with spring data JPA.
But i am not able to connect to postgresSQL instance at the time of deployment.
I am not really sure on what dependency is required for this and what is the application properties configuration.
here is the code.
application.properties
spring.datasource.url=jdbc:postgresql://google/postgres?cloudSqlInstance=<instance-name>&socketFactory=com.google.cloud.sql.postgres.SocketFactory
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
pom.xml
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>postgres-socket-factory</artifactId>
<version>1.0.12</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-postgresql</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
app.yml for deployment on flex environment:
runtime: java
env: flex
service: payment2
handlers:
- url: /.*
script: this field is required, but ignored
beta_settings:
cloud_sql_instances: <instance-name>
Thanks in advance.Please help!!!

Spring Hibernate: No Dialect mapping for JDBC type: -101

I'm working on a spring-boot app and trying to build my repository, and am having an issue with Hibernate.
Pom dependencies: (there are more, just posting what i felt relevant)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.6.Final</version>
</dependency>
Application.properties
# Properties for Spring datasources
#
# If multiple datasources are needed, the autoconfiguration will need
# to be excluded (add "(exclude = DataSourceAutoConfiguration.class)" to the
# #SpringBootApplication annotation in TankInventoryApplication).
#
# Then manual datasources will have to configured in a #Configuration annotated config class
#
spring.datasource.url=<url>
spring.datasource.username=<user>
spring.datasource.password=<password>
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
# Properties for Hibernate
#
# Use empty string for hbm2ddl.auto to suppress warning message
# hibernate.hbm2ddl.auto=validate - doesn't work
#
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.useSecondLevelCache=false
hibernate.cacheProviderClass=net.sf.ehcache.hibernate.EhCacheProvider
hibernate.cacheRegionFactoryClass=net.sf.ehcache.hibernate.EhCacheRegionFactory
hibernate.hbm2DdlAuto=
Repository:
//#Repository
//public interface PWeightTagsRepository extends JpaRepository<PTags, Integer>{
//
// #Query(value = "SELECT T FROM PTags T WHERE T.adbLDeliveryStatus = 'N' ORDER BY T.adbSequence ASC")
// List<PTags> getNewMessages();
//}
#Repository
public class PWeightTagsRepository{
#Autowired
protected EntityManager em;
public List<PTags> getNewMessages(Integer limit){
javax.persistence.Query query = em.createNativeQuery("SELECT T.* FROM GSTARTIB.P_TAGS T WHERE T.ADB_L_DELIVERY_STATUS = 'N'");
return query.getResultList();
}
}
My confusion is that, if I uncomment the first function in the repository, it will run and return results without any problem.
But, when running the second function, I get: org.hibernate.MappingException: No Dialect mapping for JDBC type: -101 error even though in my application.properties file I have a dialect declared.
What am I missing here?
Well, I found the problem.
The error message it gives seems misleading to me, as it doesn't match what the solution is.
I needed to provide the createNativeQuery function with a .class to cast the results too.
em.createNativeQuery(<query>, PTags.class) fixed the issue

Spring data JPA with HSQLDB: user lacks privilege or object not found

I'm trying to setup a simple Database with an article which may contains comments with Spring Data JPA. However as soon as I enable the comment relation on the article Hibernate throws an exception:
o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
[...]
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: PUBLIC.ARTICLE_COMMENTS
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.1.jar:2.4.1]
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.1.jar:2.4.1]
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source) ~[hsqldb-2.4.1.jar:2.4.1]
at org.hsqldb.jdbc.JDBCStatement.execute(Unknown Source) ~[hsqldb-2.4.1.jar:2.4.1]
at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-2.7.9.jar:na]
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
... 157 common frames omitted
My article class looks as follows:
#Entity
public class Article {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String abstractText;
private String author;
private Date createdAt;
private int visibility;
private int likes;
private int views;
private int commentCount;
#OneToMany(cascade=CascadeType.ALL)
private List<Comment> comments;
// getters and setters omitted
}
And the Comment:
#Entity
public class Comment {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String commentText;
private Date createdAt;
}
And the pom contains dependencies to HSQLDB, PostgreSQL, Spring Boot Starter Data JPA and Spring Boot Starter Web:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
When I remove the relation to the Comment List, it works. Any suggestions?
Seems like the spring.jpa.hibernate.ddl-auto property were the problem. Spring defaults it to create-drop for in-memory databases. However, in the current Spring Boot or HSQLDB or Hibernate version (or maybe the combination?) this seems to cause problems. After changing the value to update, it just works fine.
The exception you saw is just a WARNING, and it really doesn't mean anything broken. If you use show-sql: true options, you will see this warning is actually cause by alter table comment DROP CONSTRAINT XXXXX, which is part of Hibernate creation DDL, and hsqldb doesn't have any table when this query executed.
Changing to ddl-auto: update has its side-effect. import.sql won't work with this option.
To avoid this WARNING, you could add these lines to your application.yaml:
logging:
level:
org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl: ERROR
The issue for me was in dependency I provided.
I have a column #Column(nullable = false, columnDefinition = "text") and old dependency doesn't support this column definition. That's why I had to change
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
to this
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>

Spring - CrudRepository is not created

The CrudRepository bean
#Repository
public interface UserDao extends CrudRepository<User, Long>
{
List<User> findByFirstNameAndLastName(String firstName, String lastName);
}
for the User resource
#Entity
#Table(name="User")
public class User
{
#Id
#GeneratedValue
private long id;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
/* --- Getters,setters,default constructor -------*/
}
is not created when I start my Spring boot app
Field dao in base.package.service.UserService required a bean
of type 'base.package.dao.UserDao' that could not be found.
but the packages are definitely scanned
#SpringBootApplication(scanBasePackages= {"base.package"})
I got the strong suspicion that it has to do something with the embedded database h2 that I am using. I am trying to create the User table in schema.sql
CREATE TABLE IF NOT EXISTS User (
id INTEGER NOT NULL AUTO_INCREMENT,
first_name VARCHAR(128) NOT NULL,
last_name VARCHAR(128) NOT NULL,
PRIMARY KEY (id)
);
but as soon as I uncomment IF NOT EXISTS it throws an error (table already exists). So this firstly means that spring takes charge of created the schema. But I get the feeling that the table is not recreated because in the data.sql script
INSERT INTO User (id,first_name,last_name) VALUES (1,'Vincent', 'Vega');
I always have to manually increment the id on startup otherwise i get a
org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.USER(ID)"
Here are the jpa properties from application.properties
# below properties create schema, so schema.sql is redundant
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.initialization-mode=always
spring.jpa.database=H2
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:~/testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE
spring.datasource.name=testdb
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
The reason why I think that the table is never recreated on startup is because I get this error when the app closes
2018-02-02 09:27:47.907 INFO [restartedMain] [StandardService] Stopping service [Tomcat]
2018-02-02 09:27:47.907 WARN [localhost-startStop-1] [WebappClassLoaderBase] The web application [ROOT] appears to have started a thread named [MVStore background writer nio:C:/Users/user/testdb.mv.db] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
This is followed by the exception that UserDao bean is not created.
***************************
APPLICATION FAILED TO START
***************************
Description:
Field dao in base.package.user.service.UserService required a bean of type 'base.package.user.dao.UserDao' that could not be found.
Action:
Consider defining a bean of type 'base.package.user.dao.UserDao' in your configuration.
POM.XML
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.M5</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
/* .... */
EDIT
Here is the UserService
#Service
public class UserService
{
#Autowired private UserDao dao;
public List<User> findByFirstNameAndLastName(String firstName, String lastName)
{
return dao.findByFirstNameAndLastName(firstName, lastName);
}
public User save(final User user)
{
return dao.save(user);
}
}
EDIT 2
Now I am getting
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.project.bot.user.User
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:472)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:72)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:169)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:107)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:90)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:300)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$3(RepositoryFactoryBeanSupport.java:287)
at org.springframework.data.util.Lazy.getNullable(Lazy.java:141)
at org.springframework.data.util.Lazy.get(Lazy.java:63)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:290)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:102)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706)
... 102 common frames omitted
The table not being created should not have any impact on whether the bean is defined or not.
I think the problem you have here is that you are not instatiating your repository beans. Spring Data JPA repository beans are not picked up by component scans since they are only interfaces. The #Repository annotation actually does nothing here.
Spring Data JPA repo beans are created dynamically provided you have supplied the #EnableJpaRepositories in your configuration.
You may also need to put an #EntityScan to make sure all your #Entity's are recognised by Spring
#SpringBootApplication(scanBasePackages= {"base.package"})
#EnableJpaRepositories("base.package")
#EntityScan("base.package")

Categories