JPA - Error create table using DDL generation - spring

I'm trying to make a simple Spring application but I have trouble when I pass from H2 database to MySQL.
Here is my properties:
spring.datasource.url=jdbc:mysql://localhost:3306/spring?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=...
spring.datasource.password=...
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=update
The entity that doesn't work:
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "Option")
public class Option {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
long id;
#ManyToOne
#JoinColumn(name = "question_id", nullable = false)
private Question question;
#Column(name = "option", length = 1000, nullable = false)
private String option;
#Column(name = "is_right", nullable = false)
private boolean isRight;
}
And the error:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table option (id bigint not null, is_right bit not null, option varchar(1000) not null, question_id bigint not null, primary key (id)) engine=MyISAM" via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at ....
What is wrong ? I have nothing special or tricky in my entity

I solve my error by myself,
Option is a keyword in MySql that's why it didn't work

Related

Why OneToMany JPA association is failing while insert statement executes

Hi below is my schema definition
CREATE TABLE LOANS (
LOAN_ID NUMBER(9,0) PRIMARY KEY,
CORR_ID VARCHAR(5) NULL
);
CREATE TABLE DV_LOAN_PARTICIPANTS (
LOAN_ID NUMBER(9,0) ,
DVP_PARTICIPANT_NAME VARCHAR(50) NOT NULL,
DVP_PARTICIPANT_TYPE VARCHAR(50) NOT NULL,
PRIMARY KEY ("LOAN_ID", "DVP_PARTICIPANT_NAME")
);
LOANS Entity
#Table(name = "LOANS")
#Entity
public class Loans {
#Id
#Column(name = "LOAN_ID")
private Long loanId;
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "LOAN_ID")
#MapKey(name = "dvpParticipantName")
private Map<String, DVLoanParticipants> dvLoanParticipantsMap;
// getter and setters
}
DV_LOAN_PARTICIPANTS Entity
#Table(name = "DV_LOAN_PARTICIPANTS")
#Entity
public class DVLoanParticipants implements Serializable {
#Id
#Column(name = "LOAN_ID")
private Long loanId;
#Id
#Column(name = "DVP_PARTICIPANT_NAME")
private String dvpParticipantName;
#Column(name = "DVP_PARTICIPANT_TYPE")
private String dvpParticipantType;
// getters and setters
}
Service Class is
DVLoanParticipants dvLoanParticipants = new DVLoanParticipants();
dvLoanParticipants.setLoanId(Long.valueOf("196801758"));
dvLoanParticipants.setDvpParticipantName("VKP");
dvLoanParticipants.setDvpParticipantType("Developer");
Loans loanInsert = new Loans();
loanInsert.setLoanId(Long.valueOf("196801758"));
Map<String,DVLoanParticipants> partyMap = new HashMap<>();
partyMap.put("VKP",dvLoanParticipants);
loanInsert.setDvLoanParticipantsMap(partyMap);
repository.save(loanInsert);
But when i am executing the save i am getting error as
NULL not allowed for column "LOAN_ID"; SQL statement:
insert into dv_loan_participants (dvp_participant_type, loan_id, dvp_participant_name) values (?, ?,
?)
Git Hub Code
https://github.com/vinoykp/spring-jpa/tree/master/spring-boot-hibernate-crud-demo
I had the similar question
Why Value is not getting assigned in JPA for insert statement
What is the issue in association?

Parent key not found with #MapsId

I am using Java8, SpringBoot 2.3.7 and JPA with Oracle
There is this legacy table (I cannot touch it, as it is in production with other applications)
TRANSFE (TRA_ID_PK NUMBER, ACCOUNT_ID NUMBER, .... )
CONSTRAINT "TRANSFE_UNIQUE" UNIQUE ("TRA_ID_PK")
In my new application some of the new Transfe will be TransfeIn, with only one field, so I created this table
TRANSFE_IN (ID NUMBER, ....)
CONSTRAINT "TRANSF_IN_PK" PRIMARY KEY ("ID")
Everything works fine with Jpa:
#Entity
#Table(name = "TRANSFE")
public class Transfe implements Serializable {
#Id
#Column(name = "TRA_ID_PK")
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_TRANSFES")
#SequenceGenerator(name="SEQ_SW_TRANSFERENCIAS", sequenceName="SEQ_TRANSFES", allocationSize=1)
private Long id;
#ManyToOne
#JoinColumn(name = "TRA_ID")
private Account account;
#OneToOne(cascade = {CascadeType.ALL})
#PrimaryKeyJoinColumn
private TransfeIn transfeIn;
and
#Entity
#Table(name = "TRANSFE_IN")
public class TransferenciaEntrant {
#Id
private Long id;
#MapsId
#OneToOne(cascade = {CascadeType.ALL}, mappedBy = "transfeIn")
#JoinColumn(name = "id")
private Transfe transfe;
The problem raises when I add this to TRANSFE_IN
CONSTRAINT "TRANSFE_IN_FK" FOREIGN KEY ("ID") REFERENCES "TRANSFE" ("TRA_ID_PK")
So when there is a new TransfeIn to be stored with
accountRepository.save(account)
(Account has a #OneToMany(mappedBy = "account", cascade = CascadeType.ALL) List transfes), I get
SQLIntegrityConstraintViolationException: ORA-02291: integrity constraint (TRANSFE_ENTR_FK) violated - parent key not found
In the logs, I can see how a new TRANSFE_IN row with the right ID (taken from SEQ_TRANSFES) is being inserted. But the table TRANSFE is empty, yet.
What am I doing wrong? Should I not use the FK? Or there is something in the annotations to be changed?

ERROR: UPDATE or DELETE statement on table

In a project with Spring Boot and Spring JPA I Have two entities FunctionConfiguration and InvokeFunctionResult.
#Entity
#Table(name = "function_configuration")
public class FunctionConfigurationEntity {
#Id
#Column(name = "id_function_configuration")
#GeneratedValue(strategy = IDENTITY)
private Integer idFunctionConfiguration;
}
#Entity
#Table(name = "invoked_function_result")
public class InvokedFunctionResultEntity {
#Id
#Column(name = "id_invoked_result_function")
#GeneratedValue(strategy = IDENTITY)
private Integer idInvokedResultFunction;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "function_configuration_id", nullable = false, foreignKey = #ForeignKey(name = "function_configuration_fk"), referencedColumnName = "id_function_configuration")
private FunctionConfigurationEntity functionConfiguration;
}
The InvokeFunctionResult has foreign key the id of the FunctionConfiguration.
If I try to do a delete with an id of a functionConfiguration that is present in the InvokeFunctionResult:
#Transactional
#Modifying
#Query(value = "DELETE FROM FunctionConfigurationEntity fce WHERE fce.idFunctionConfiguration = idFunctionConfiguration")
void deleteByFunctionConfigurationId(#Param("idFunctionConfiguration") Integer functionConfigurationId);
I get the following error: Caused by: org.postgresql.util.PSQLException: ERROR: UPDATE or DELETE statement on table "function_configuration" violates foreign key constraint "function_configuration_fk" on table "invoked_function_result"
How can I fix it?

Hibernate: Find entity from one to many table

I have two tables
CREATE TABLE `heroic_quality`
(
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(515) NOT NULL UNIQUE,
PRIMARY KEY (`id`)
);
CREATE TABLE `hero`
(
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(515) NOT NULL UNIQUE,
`quality_id` INT DEFAULT NULL,
FOREIGN KEY (`quality_id`) REFERENCES heroic_quality (id),
PRIMARY KEY (`id`)
);
And the objects in hibernate are
#Table(name = "heroic_quality")
#Entity(name = "heroic_quality")
public class HeroicQuality
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
protected long id;
#Column(name = "name", nullable = false, unique = true)
private String name;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "id")
#Fetch(FetchMode.SELECT)
private List<Hero> heroes;
//ommited getters and setters for shortness
}
#Table(name = "hero")
#Entity(name = "hero")
public class Hero
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
protected long id;
#Column(name = "name", nullable = false, unique = true)
private String name;
//ommited getters and setters for shortness
}
As you see my Hero class doesn't have reference to heroic quality, and I would like to keep it that way.
Also I have a repository
#Repository
public interface HeroicQualityDAO
extends PagingAndSortingRepository<HeroicQuality, Long>
{
Optional<HeroicQuality> findByName(String name);
List<HeroicQuality> findByOrderByIdDesc();
}
What I would like to do is have a method such as
Optional<HeroicQuality> findByHeroName(String heroName)
Such that if given a name of hero from Hero table I will be able to get heroic quality object.
How can I make such a method?
Is there any way I can get heroic quality object without having a reference to it in the hero object?
How can I go about doing that?
Add the following method to HeroicQualityDAO.
Optional<HeroicQuality> findByHeroesName(String heroName);
If you are not happy with the method name, you can do
#Query("Select h from HeroicQuality hq join hq.heros h where h.name = :name")
Optional<HeroicQuality> findByHeroName(String name);

Could not fetch the SequenceInformation from the database ERROR but still everything works

I've created user and userRole tables
user entity
#Entity
#Table(name = "USERS")
public class User {
#Id
#Column(name = "USERNAME", nullable = false, unique = true)
private String username;
#Column(name = "PASSWORD", nullable = false)
private String password;
#Column(name = "ENABLED", nullable = false)
private boolean enabled = true;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.EAGER)
private Set<UserRole> userRole = new HashSet<>();
userRole entity
#Entity
#Table(name = "USER_ROLES", uniqueConstraints = #UniqueConstraint(
columnNames = { "ROLE", "USERNAME" }))
public class UserRole {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "user_role_id",
unique = true, nullable = false)
private Integer userRoleId;
#Column(name = "ROLE")
private String role;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "USERNAME")
private User user;
When i launch my app i get an Error and this stack trace:
ERROR JdbcEnvironmentImpl:420 - Could not fetch the SequenceInformation from the database
org.h2.jdbc.JdbcSQLException: Column "start_with" not found [42122-197]
But i don't have any 'start_with' columns. Before my UserRole entity was without userRoleId column and everything worked fine but then i added it to do 'role' column not unique and then this happened. But still everything works fine, i just disturbed by this error, what can be the couse of it?
I suggest checking your Hibernate dialect.
I had a similar error because of a start_value column that Hibernate was looking for in sequences of my PostgresQL database. This field name is a default value in Hibernate's SequenceInformationExtractorLegacyImpl class which has many subclasses, each depending on your precise database server and its version. Hibernate loads the right class according to the dialect you specify.
In my case, I was using the org.hibernate.dialect.PostgreSQLDialect dialect, a (deprecated) class meant to be used with a PostgesQL 8.2 version. I switched to org.hibernate.dialect.PostgreSQL9Dialect since my database was hosted on a PostgresQL 9 server. And the issue was gone.

Resources