Spring JPA - how to set data.sql to add data if not exist, ignore if exists - spring-boot

Hi i am creaeting rest api spring boot jpa & mysql. i want this to be automated as possible so i drop the database and schema and want spring to create all for me. i am adding data into mysql using data.sql. When i start spring boot, i 1 2 it to add into the table (which spring jpa help to create).
Tis is from my application.properties
spring.jpa.show-sql=true
spring.h2.console.enabled=true
spring.datasource.url=jdbc:mysql://localhost:3306/mockashop
spring.datasource.username=root
spring.datasource.password=root
spring.data.jpa.repositories.bootstrap-mode=default
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.properties.hibernate.format.sql=true
spring.jpa.hibernate.ddl-auto=update
spring.sql.init.mode=always
here is my data.sql:
INSERT INTO `mockashop`.`user` (`user_id`, `user_role`, `user_contact`, `user_email`, `user_name`, `user_pswd`, `user_wallet`) VALUES ('20003', 'ROLE_USER', '+6592212152', 'shah3#gmail.com', 'shah3', 'shahshah', '777.55');
model:
#Entity
#Data
#SequenceGenerator(name="seq2", initialValue=2000, allocationSize=1)
public class User {
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq2")
#Id
private int user_id;
#NotNull(message = "Name cannot be blank")
#Size(min=5, message = "Name must contain atleast 5 character")
private String user_name;
#NotNull(message = "Email cannot be blank")
#Email(message = "Enter valid email")
#Size(min=5, message = "Email must contain atleast 5 character")
private String user_email;
#Size(min=5, message = "Password must contain atleast 8 character")
#NotNull(message = "Password cannot be blank")
private String user_pswd;
#Size(min=5, message = "Contact must contain atleast 8 character")
#NotNull(message = "Password cannot be blank")
private String user_contact;
#NotNull(message = "Wallet cannot be blank")
private BigDecimal user_wallet;
private String USER_ROLE;
}
1ST PROB
spring hibernate will create the table for me if i create the schema first else it will give me error:
Caused by: java.sql.SQLSyntaxErrorException: Unknown database 'mockashop'
How do i resolve this?
2ND PROB
so i create the schema, then start spring, which give me this error:
Caused by: java.sql.SQLSyntaxErrorException: Table 'mockashop.user' doesn't exist
it will go away until i remove data.sql. now spring boot is finally running.
3RD PROB
mysql has the table created for me but no data. so i add back the data.sql. restart spring. now data is added.
4TH PROB
i do other changes and restart spring it gives me this error:
Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '20001' for key 'user.PRIMARY'
i have to remove data.sql then the error is gone.
is there a way to resolve all this ?

1st
While h2 will create the schema for you automatically, MySQL won't automatically create the database for you. You have to do it manually.
Cant create a mysql database using Spring Boot
2nd and 3rd
If you are just adding just one line in mockashop.user, you can try adding the data using #EventListner
You can then remove the data.sql file
#Component
public class Data {
#Autowired
UserRepository userRepository;
#EventListener
public void appReady(ApplicationReadyEvent event){
rolesRepository.save(new User('20003', 'ROLE_USER', '+6592212152', 'shah3#gmail.com', 'shah3', 'shahshah', '777.55'));
}
}
4th
That is because every time you run this application the spring tries to add the same value over and over again and the user_id would have a UNIQUE constraint. That's why you are getting that error.
I believe the solution in the 2nd and 3rd point would also solve this problem as the save method of JPA would update the values in the database if the primary key value that is being passed is already present in the database.

Related

hibernate not use #column(name='') annotation

I use springboot 2.6 and postgres 15 and hibernate 5.7
I use database Generate persistence Mapping to make entity from database schema;
When I run application with this config:
spring.jpa.hibernate.ddl-auto=validate
table properties name not work.
for example this is my field:
#Basic
#Column(name = "isEnabled", nullable = false)
private boolean isEnabled;
When I run applicataion get this error:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing column [is_enabled] in table [analytics]
Can you try to add the following annotation to your Analytics entity definition?
#Table(name = "analytics", schema = "public")
there are 2 problems. first is field name. seccond is table name;
first problem fix with this config in application.properties:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
this fix first problem. but seccond problem not fix.
you should change table name with this trick:
#Table(name = ""analytics"")

Heroku shows Whitelabel Error Page but not on localhost

I have a Spring boot application with PostgreSQL. The app run very well on localhost with all the data from the PostgreSQL. I have successful upload the app to Heroku and migrated the database to Heroku PostgreSQL. The problem is when I click some of the links that retrieve data from PostgreSQL shows a White Error page. But on localhost every thing works fine.
Below is the Controller that link to the White Error Page.
#Controller
public class MahubiriController {
#Autowired
private MisaleRepository misaleRepository;
#GetMapping("/masomo/somolaleo")
public String masomoAngalia(Model model){
model.addAttribute("masomoYote", misaleRepository.findAllOrderByDateDesc() );
return "masomo";
} }
Below is the repository
#Repository
#Transactional
public interface MisaleRepository extends JpaRepository <Misale, String> {
#Query(value ="SELECT * FROM misale ORDER BY date DESC" , nativeQuery = true)
public List<Misale> findAllOrderByDateDesc();
}
Below is the Entity for the particular object
#Entity
#Table(name = "misale")
public class Misale {
#Id
#Column(name ="date")
private String date;
#Lob
#Column(name ="first_reading", columnDefinition="text")
private String firstReading;
#Lob
#Column(name ="second_reading", columnDefinition="text")
private String secondReading;
// Constructors, getter and setters
}
Below is the Query used to create the particular table on Postgresql
CREATE TABLE misale(date VARCHAR(20) NOT NULL PRIMARY KEY,
first_reading TEXT NOT NULL,
second_reading TEXT,gospel TEXT NOT NULL);
What could possibly be wrong on Heroku to lead to a White Error Page and not on a local host.
Update :
After implementing the Exception handling as suggested by # krishnkant jaiswal, I receive message "Unable to access lob str…le to access lob stream" as below.
timestamp "2021-04-03T01:26:43.791+00:00"
message "Unable to access lob stream; nested exception is org.hibernate.HibernateException: Unable to access lob stream"
details "uri=/masomo/somolaleo"
With the help of Exception handling and a long research, On my side it shows that you cannot use
#Lob and #Column(columnDefinition="text")
So I had to remove #Lob and leave #Column(columnDefinition="text")
#Column(columnDefinition="text")
Now I cloud retrieve the data from PostgreSQL without error.
Hope it might help someone else in future.

Hibernate creates new Tables but won't modify/add Columns

Looking for next debugging steps. I'm using Hibernate with Spring Boot, with my ddl setting set to update (I realize the hibernate setting is redundant but I just wanted to be sure):
application.properties
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
hibernate.hbm2ddl.auto=update
I've just added a new Entity, which succesfully created. But when adding an additional field, profileImageURI2, nothing is ever run to attempt to add it:
#Entity
#Data
public class User {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String profileImageURI;
private String profileImageURI2;
}
Is there any additional config that will control the modification of existing tables? The user also has all permissions for the database.

Sequence "HIBERNATE_SEQUENCE" not found; SQL statement

In my spring mvc app, i have the following object. I am trying to make a visual of data using devtool in my app.
#Entity
#Data
public class ConsultationRequest {
#Id
#GeneratedValue
private Long id;
private String name;
private String email;
private String purpose;
private String programme;
private int year;
private String language;
private String comments;
#Enumerated(EnumType.STRING)
private ConsultationStatus status;
}
Then i used the jpa to make the entity:
#Repository
public interface ConsultationRequestRepository extends JpaRepository<ConsultationRequest, Long> {
}
The problem is when i load my application, i face with 2 errors:
Unsuccessful: drop sequence hibernate_sequence
[36morg.hibernate.tool.hbm2ddl.SchemaExport Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
Then when i open the
http://localhost:8080/h2-console/
I cannot see the table.
It seems that the in the boot process, table is not made.
Update your code as below:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
As you have not specified a sequence table name, hibernate will look for a sequence table named as hibernate_sequence and use it as default.
For Oracle/Postgres, increment fields used are sequence tables.
In MySql, there are increment fields that automatically increment.
If someone is getting this error with Spring Boot testing(with H2) , we have to use following in the application.properties(or whatever profile we are using) :
spring.jpa.hibernate.ddl-auto=create-drop
Setting the following property in the properties file helped me solve the hibernate_sequence problem for hibernate 5.4v
spring:
jpa:
hibernate:
use-new-id-generator-mappings: false
Check persistence.xml
property name="hibernate.hbm2ddl.auto" value="create"
not hdm2ddl
This worked in my case.
SQL operation ERROR when start app spring-boot.
I added the setting in spring properties and solved: in the spring:jpa.hibernate.ddl-auto= create-drop to hibernate be able create or drop table automatically.
If you use a 2nd cache with liquidbase, you have to add the sequence in the changelog like this:
<changeSet author="liquibase-docs"
id="createSequence-example">
<createSequence catalogName="cat" cycle="false"
incrementBy="1" ordered="true" schemaName="public"
sequenceName="hibernate_sequence" startValue="0" />
</changeSet>
For spring-boot 2.7.x and h2 2.x you need to add MODE=LEGACY; in the database connection:
example application.yml:
spring:
datasource:
url: jdbc:h2:mem:test;MODE=LEGACY;
exemple application.properties:
spring.datasource.url=jdbc:h2:mem:test;MODE=LEGACY;
For Mysql:
the auto-increment is not added, modify ur table:
ALTER TABLE table_name MODIFY COLUMN id BIGINT AUTO_INCREMENT=1

Hibernate "could not get next sequence value" oracle

i get this error could not get next sequence value when I try to save this Entity with Hibernate:
package beans;
import javax.persistence.*;
#Entity
#Table(schema = "EVGENY")
public class Article {
#SequenceGenerator(name="ArticleGen", sequenceName="ARTICLESEC")
#Id
#GeneratedValue(generator= "ArticleGen")
private int id;
#Column(name="title")
private String title;
#Column(name="text")
private String text;
#Column(name="postat")
private String postat;
#ManyToOne
#JoinColumn(name = "USER_ID")
private UserAcc user;
public Article(){
}
Get Set...
}
insert into article (title) values('asdfaf');
in Oracle SQL Developer this insert into article (title) values('asdfaf'); works well.
if i set id variable explicitly ( Article a = new Article();a.setId(3); )
everything is OK. I double checked the name of the sequence.
Check user permissions on the sequence. Most of the time it is grant issue
I know a lot of reasons to get this exception. Maybe you can check the questions and give me some more details about your problem:
check if the 'hibernate.dialect' is set to Oracle?
permission on sequence ok (schemata, select etc.)?
is there some trigger behind the table and throwing plsql error?
some other plsql that could break the insert?
is the transaction broken?
was there an exception (sometimes silent) somwhere before the call of create (like stale state or out of bounce) so that transaction is marked for rollback?
is there a connection is erroneous error before exception?
is the entity maybe already attached (check with contains)?
do you use spring or another framework where you can add exception resolvers or translators?
which version of oracle database do you use? 10 or 11? and are the used drivers correct?
is there a findSingle call before that does not return any value?

Resources