Hibernate throws SQLGrammarException - java

The entity class is :
#Entity
#Table(name = "movieDetail")
public class MovieDetailImpl implements MovieDetail {
#Id
// primary key
#Column(name = "idmovieDetail")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "cast")
private String cast;
#Column(name = "producer")
private String producer;
#Column(name = "director")
private String director;
#Column(name = "trailer")
private URL trailer;
#Column(name = "photo")
private URL photo;
#Column(name = "plot")
private URL plot;
#Column(name = "desc")
private String desc;
#Column(name = "moreDetails")
private URL moreDetails;
// Getters/Setters
}
I am trying to persist a MovieDetail entity with only cast set. Rest of the fields are null.
Hibernate throws the below exception:
014-08-17 21:47:35 INFO TransactionFactoryInitiator:62 - HHH000399:
Using default transaction strategy (direct JDBC transactions)
2014-08-17 21:47:35 INFO ASTQueryTranslatorFactory:47 - HHH000397:
Using ASTQueryTranslatorFactory
2014-08-17 21:47:36 INFO HibernateTransactionManager:341 - Using
DataSource
[org.springframework.jdbc.datasource.DriverManagerDataSource#1fba434a]
of Hibernate SessionFactory for HibernateTransactionManager
Hibernate: insert into movieDetail (cast, desc, director, moreDetails,
photo, plot, producer, trailer) values (?, ?, ?, ?, ?, ?, ?, ?)
2014-08-17 21:47:36 WARN SqlExceptionHelper:144 - SQL Error: 1064,
SQLState: 42000
2014-08-17 21:47:36 ERROR SqlExceptionHelper:146 - You have an error
in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'desc, director,
moreDetails, photo, plot, producer, trailer) values ('testGetAll' at
line 1
2014-08-17 21:47:36 INFO GenericApplicationContext:873 - Closing
org.springframework.context.support.GenericApplicationContext#40266966:
startup date [Sun Aug 17 21:47:34 PDT 2014]; root of context hierarchy
In my 'database.properties' , I have :
jdbc.dialect=org.hibernate.dialect.MySQL5Dialect
I am using a MySQL Community Server 5.6.20. and the mysql java driver version dependency defined in maven's pom.xml is
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.28</version>
</dependency>
Am I missing anything here?

You have a column named desc, and desc is a reserved work in MySql (and many other databases).
You can:
From this and this you can make hibernate escape all column and table names: hibernate.globally_quoted_identifiers=true (in your persistence.xml, or hibernate configuration.
Change the name of the column
From this you can escape only this identifier using:
#Column(name="\"desc\"")
Also, if is not a legacy database, please consider renaming.

Related

spring boot jdbcTemplate.query throws table not found auto converting table name to upper case

i have a jdbcTemplate.query method with query bit complex with multiple left joins, so its difficult for me to implement interface based repository methods.
I am using a MySQL db from AWS RDS.
when the query is executing spring boot jpa automatically converting table name to upper case and it throws error as: table not found.
exception is:
with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [SELECT DISTINCT test_desc FROM test_name_table]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "TEST_NAME_TABLE" not found; SQL statement:
SELECT DISTINCT test_desc FROM test_name_table [42102-200]] with root cause
org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "TEST_NAME_TABLE" not found; SQL statement:
SELECT DISTINCT test_desc FROM test_name_table [42102-200]
here are the solutions i have tried:
from application.properties:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.DefaultNamingStrategy
database url:
spring.datasource.dataSourceProperties.serverName=test-instance.us-east-1.rds.amazonaws.com;DATABASE_TO_UPPER=FALSE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;
as you see above sql query, i have even put the table name inside backtick. but no luck.
I tried to rename the table name in MySQL to TEST_NAME_TABLE, but still no luck.
any recommended fix for this?
its a good practice use #Table(name = "table_name") for a model and #Column(name = "column_name") annotation for every column in your Model.java
and use #Query("some query in SQL") for every query you use in ModelRepository.java
example:
#Entity
#Table
public class Employee implements Serializable {
#Id
#Column(name = "emp_id")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
#Column(name = "jobTitle")
private String jobTitle;
#Column(name = "phone")
private String phone;
#Column(name = "imagUrl")
private String imageUrl;
#Column(name = "employeeCode")
private String employeeCode;
}
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
#Query("SELECT s FROM Employee s WHERE s.email = ?1")
Optional<Employee> findEmployeeByEmail(String email);
}

Insert row using jdbctemplate with PrimaryKey generated by #GeneratedValue

I am inserting a row into an Oracle table in a Spring Boot application. The Primary Key needs to be generated using annotations. I have an entity model that represents the table:
#Entity
#Table(name="PURCH_TENDR")
public class LhlPurchTendrModel implements Serializable {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
#Column(name="PURCH_TENDR_ID")
private String purchTendrId;
#Column(name="CREATED_BY_NM")
private String createdByNm;
#Column(name="CREATED_DT")
private Timestamp createdDt;
#Column(name="UPDATED_BY_NM")
private String updatedByNm;
#Column(name="UPDATED_DT")
private Timestamp updatedDt;
#Column(name="MODIFY_BY_NM")
private String modifyByNm;
#Column(name="MODIFY_DT")
private Timestamp modifyDt;
#Column(name="CARRIER_TENDER_ID")
private long CarrierTenderId;
#Column(name="EVENT_GMT_TM")
private Timestamp EventGmtTm;
#Column(name="PURCH_COST_ID")
private int PurchCostId;
#Column(name="LAT")
private float Lat;
#Column(name="LON")
private float Lon;
#Column(name="CITY_NM")
private String cityNm;
#Column(name="STATE_CD")
private String stateCd;
#Column(name="CARER_EDI_NBR")
private String carerEdiNbr;
#Column(name="EVENT_STAT_CD")
private String eventStatCd;
#Column(name="ETN_TM")
private Timestamp EtnTm;
#Column(name="PCKUP_NBR")
private String PickupNbr;
#Column(name="VIN")
private String Vin;
#Column(name="EQUIP_NBR")
private String EquipNbr;
#Column(name="EQUIP_PREFIX")
private String EquipPrefix;
There are also getters and setters for these member variables.
I use a Repository class to implements a jdbctemplate to insert the row.
When I use this variation of the insert, I get the error that the column type is invalid:
public boolean insertPurchaseInfo(LhlPurchTendrModel lhlPurchTendrModel) throws SQLException {
boolean success= false;
String ds = lhlJdbcTemplate.getDataSource().getConnection().getSchema();
LOGGER.info("Schema and Insert Purchase Info {}", ds);
String insertSequenceNbrSQLStatement = "INSERT INTO purch_tendr(created_by_nm, created_dt, modify_by_nm, modify_dt, carrier_tender_id, purch_cost_id, event_stat_cd, equip_nbr, equip_prefix) " +
"VALUES (?, SYSDATE, ?, SYSDATE, ?, ?, ?, ?, ?)";
try{
int rowsInserted = lhlJdbcTemplate.update(
insertSequenceNbrSQLStatement,
new Object[] {lhlPurchTendrModel});
if(rowsInserted > 0){
success = true;
}
}
When I try to insert using this code, I get the error 'cannot insert NULL into table Purch_Tendr column Purch_Tendr_Id.
public boolean insertPurchaseInfo(LhlPurchTendrModel lhlPurchTendrModel) throws SQLException {
boolean success= false;
String ds = lhlJdbcTemplate.getDataSource().getConnection().getSchema();
LOGGER.info("Schema and Insert Purchase Info {}", ds);
String insertSequenceNbrSQLStatement = "INSERT INTO purch_tendr(created_by_nm, created_dt, modify_by_nm, modify_dt, carrier_tender_id, purch_cost_id, event_stat_cd, equip_nbr, equip_prefix) " +
"VALUES (?, SYSDATE, ?, SYSDATE, ?, ?, ?, ?, ?)";
try{
int rowsInserted = lhlJdbcTemplate.update(
insertSequenceNbrSQLStatement,
new Object[]{lhlPurchTendrModel.getCreatedByNm(), lhlPurchTendrModel.getModifyByNm(), lhlPurchTendrModel.getCarrierTenderId(), lhlPurchTendrModel.getPurchCostId(),
lhlPurchTendrModel.getEventGmtTm(), lhlPurchTendrModel.getEquipNbr(), lhlPurchTendrModel.getEquipPrefix()});
if(rowsInserted > 0){
success = true;
}
}
I am not sure how to use the #Entity class with JdbcTemplate. How do I indicate to JdbcTemplate to generate the primary key value?
You can't because #Entity and all annotations you use such as #GeneratedValue, #GenericGenerator etc come from JPA while JdbcTemplate behind scene is based on JDBC only which does not know anything about JPA.
If you want to use JPA to manage your data , what you need to look is to choose a JPA implementation (e.g Hibernate is a popular one) and study how to use it through JPA interface but not looking at JdbcTemplate.
Once you get the basic ideas to manage data using JPA , you may consider to look at spring data which is a more high level tool build on top of pure JPA that can help to implement repository / DAO kind of stuff for managing and querying the data.

Hibernate 5 update after insert

I'm upgrading my Hibernate version from 3 to 5. Now I have a few tests that fall with an error:
Caused by: java.sql.BatchUpdateException: The UPDATE statement conflicted with the FOREIGN KEY constraint "application_dme_provider_fk1". The conflict occurred in database "ruslans_00_develop_dev_easycare", table "dbo.application", column 'application_code'.
It occurs when an entity Organisation is saving.
Debug logs show this:
2019-01-22 07:17:14,962 DEBUG [main] SQL - insert into organization (country_code, organization_name, party_id) values (?, ?, ?)
2019-01-22 07:17:14,984 DEBUG [main] SQL - select partyrole0_.party_id as party_id2_109_0_, partyrole0_.party_role_type_code as party_ro1_109_0_ from party_role partyrole0_ where partyrole0_.party_id=? and partyrole0_.party_role_type_code=?
2019-01-22 07:17:14,988 DEBUG [main] SQL - insert into party_role (party_id, party_role_type_code) values (?, ?)
2019-01-22 07:17:15,011 DEBUG [main] SQL - select dmeprovide0_.party_id as party_id1_39_0_, dmeprovide0_.party_role_type_code as party_ro2_39_0_, dmeprovide0_.national_provider_identifier as national3_39_0_ from dme_provider dmeprovide0_ where dmeprovide0_.party_id=? and dmeprovide0_.party_role_type_code=?
2019-01-22 07:17:15,018 DEBUG [main] SQL - insert into dme_provider (national_provider_identifier, party_id, party_role_type_code) values (?, ?, ?)
2019-01-22 07:17:15,953 DEBUG [main] SQL - select organisati0_.id as id1_102_4_, organisati0_.account_number as account_2_102_4_, organisati0_.country_code as country13_102_4_, organisati0_.default_billing_plan_id as default14_102_4_, organisati0_.default_plan_updated_by as default15_102_4_, organisati0_.image_id as image_i16_102_4_, organisati0_.name as name3_102_4_, organisati0_.password_reset_duration_months as password4_102_4_, organisati0_.password_reset_required as password5_102_4_, organisati0_.patient_group_layout_code as patient17_102_4_, organisati0_.physician_access as physicia6_102_4_, organisati0_.default_plan_updated_on as default_7_102_4_, organisati0_.primary_contact_information_id as primary18_102_4_, organisati0_.first_name as first_na8_102_4_, organisati0_.last_name as last_nam9_102_4_, organisati0_.title as title10_102_4_, organisati0_.subscription_level as subscri11_102_4_, organisati0_.type as type12_102_4_, applicatio1_.organisation_id as organisa6_12_6_, applicatio1_.application_code as applicat1_12_6_, applicatio1_.party_id as party_id5_12_6_, applicatio1_.party_role_type_code as party_ro2_12_6_, applicatio1_.application_code as applicat1_6_, applicatio1_.application_code as applicat1_12_0_, applicatio1_.party_id as party_id5_12_0_, applicatio1_.party_role_type_code as party_ro2_12_0_, applicatio1_.is_activating_flag as is_activ3_12_0_, applicatio1_.migrated_to_budapest_flag as migrated4_12_0_, applicatio1_.organisation_id as organisa6_12_0_, image2_.id as id1_79_1_, image2_.description as descript2_79_1_, image2_.image as image3_79_1_, image2_.name as name4_79_1_, image2_.type as type5_79_1_, contactinf3_.id as id1_27_2_, contactinf3_.address_id as address13_27_2_, contactinf3_.email as email2_27_2_, contactinf3_.phone_number_0 as phone_nu3_27_2_, contactinf3_.phone_type_0 as phone_ty4_27_2_, contactinf3_.phone_number_1 as phone_nu5_27_2_, contactinf3_.phone_type_1 as phone_ty6_27_2_, contactinf3_.phone_number_2 as phone_nu7_27_2_, contactinf3_.phone_type_2 as phone_ty8_27_2_, contactinf3_.phone_number_3 as phone_nu9_27_2_, contactinf3_.phone_type_3 as phone_t10_27_2_, contactinf3_.phone_number_4 as phone_n11_27_2_, contactinf3_.phone_type_4 as phone_t12_27_2_, contactinf3_.time_zone_code as time_zo14_27_2_, address4_.id as id1_1_3_, address4_.address_line1 as address_2_1_3_, address4_.address_line2 as address_3_1_3_, address4_.city_suburb as city_sub4_1_3_, address4_.country_code as country_6_1_3_, address4_.postcode as postcode5_1_3_, address4_.state_id as state_id7_1_3_ from organisation organisati0_ left outer join application_dme_provider applicatio1_ on organisati0_.id=applicatio1_.organisation_id left outer join image image2_ on organisati0_.image_id=image2_.id left outer join contact_information contactinf3_ on organisati0_.primary_contact_information_id=contactinf3_.id left outer join address address4_ on contactinf3_.address_id=address4_.id where organisati0_.id=?
2019-01-22 07:17:15,969 DEBUG [main] SQL - select applicatio0_.application_code as applicat1_12_0_, applicatio0_.party_id as party_id5_12_0_, applicatio0_.party_role_type_code as party_ro2_12_0_, applicatio0_.is_activating_flag as is_activ3_12_0_, applicatio0_.migrated_to_budapest_flag as migrated4_12_0_, applicatio0_.organisation_id as organisa6_12_0_ from application_dme_provider applicatio0_ where applicatio0_.application_code=? and applicatio0_.party_id=? and applicatio0_.party_role_type_code=?
2019-01-22 07:17:15,973 DEBUG [main] SQL - select location0_.id as id1_90_2_, location0_.active as active2_90_2_, location0_.contact_information as contact_4_90_2_, location0_.name as name3_90_2_, location0_.organisation_id as organisa5_90_2_, contactinf1_.id as id1_27_0_, contactinf1_.address_id as address13_27_0_, contactinf1_.email as email2_27_0_, contactinf1_.phone_number_0 as phone_nu3_27_0_, contactinf1_.phone_type_0 as phone_ty4_27_0_, contactinf1_.phone_number_1 as phone_nu5_27_0_, contactinf1_.phone_type_1 as phone_ty6_27_0_, contactinf1_.phone_number_2 as phone_nu7_27_0_, contactinf1_.phone_type_2 as phone_ty8_27_0_, contactinf1_.phone_number_3 as phone_nu9_27_0_, contactinf1_.phone_type_3 as phone_t10_27_0_, contactinf1_.phone_number_4 as phone_n11_27_0_, contactinf1_.phone_type_4 as phone_t12_27_0_, contactinf1_.time_zone_code as time_zo14_27_0_, address2_.id as id1_1_1_, address2_.address_line1 as address_2_1_1_, address2_.address_line2 as address_3_1_1_, address2_.city_suburb as city_sub4_1_1_, address2_.country_code as country_6_1_1_, address2_.postcode as postcode5_1_1_, address2_.state_id as state_id7_1_1_ from location location0_ left outer join contact_information contactinf1_ on location0_.contact_information=contactinf1_.id left outer join address address2_ on contactinf1_.address_id=address2_.id where location0_.id=?
2019-01-22 07:17:15,983 DEBUG [main] SQL - select billingpla0_.organisation_id as organisa1_15_0_, billingpla0_.billing_plan_id as billing_2_15_0_, billingpla1_.id as id1_14_1_, billingpla1_.allowed_for_all_orgs_flag as allowed_2_14_1_, billingpla1_.card_only_flag as card_onl3_14_1_, billingpla1_.data_start_at_setup_flag as data_sta4_14_1_, billingpla1_.data_start_offset_days as data_sta5_14_1_, billingpla1_.night_profile_duration_days as night_pr6_14_1_, billingpla1_.plan_availability_end_date as plan_ava7_14_1_, billingpla1_.plan_availability_start_date as plan_ava8_14_1_, billingpla1_.plan_code as plan_cod9_14_1_, billingpla1_.plan_duration_days as plan_du10_14_1_, billingpla1_.plan_name as plan_na11_14_1_, billingpla1_.summary_data_duration_days as summary12_14_1_, billingpla1_.troubleshooting_duration_days as trouble13_14_1_, billingpla1_.version as version14_14_1_ from billing_plan_organisation billingpla0_ inner join billing_plan billingpla1_ on billingpla0_.billing_plan_id=billingpla1_.id where billingpla0_.organisation_id=?
2019-01-22 07:17:16,005 DEBUG [main] SQL - select locations0_.organisation_id as organisa5_90_0_, locations0_.id as id1_90_0_, locations0_.id as id1_90_1_, locations0_.active as active2_90_1_, locations0_.contact_information as contact_4_90_1_, locations0_.name as name3_90_1_, locations0_.organisation_id as organisa5_90_1_, contactinf1_.id as id1_27_2_, contactinf1_.address_id as address13_27_2_, contactinf1_.email as email2_27_2_, contactinf1_.phone_number_0 as phone_nu3_27_2_, contactinf1_.phone_type_0 as phone_ty4_27_2_, contactinf1_.phone_number_1 as phone_nu5_27_2_, contactinf1_.phone_type_1 as phone_ty6_27_2_, contactinf1_.phone_number_2 as phone_nu7_27_2_, contactinf1_.phone_type_2 as phone_ty8_27_2_, contactinf1_.phone_number_3 as phone_nu9_27_2_, contactinf1_.phone_type_3 as phone_t10_27_2_, contactinf1_.phone_number_4 as phone_n11_27_2_, contactinf1_.phone_type_4 as phone_t12_27_2_, contactinf1_.time_zone_code as time_zo14_27_2_, address2_.id as id1_1_3_, address2_.address_line1 as address_2_1_3_, address2_.address_line2 as address_3_1_3_, address2_.city_suburb as city_sub4_1_3_, address2_.country_code as country_6_1_3_, address2_.postcode as postcode5_1_3_, address2_.state_id as state_id7_1_3_, timezone3_.time_zone_code as time_zon1_144_4_, timezone3_.time_zone_name as time_zon2_144_4_ from location locations0_ left outer join contact_information contactinf1_ on locations0_.contact_information=contactinf1_.id left outer join address address2_ on contactinf1_.address_id=address2_.id left outer join time_zone timezone3_ on contactinf1_.time_zone_code=timezone3_.time_zone_code where locations0_.organisation_id=? order by locations0_.name
2019-01-22 07:17:16,015 DEBUG [main] SQL - insert into application_dme_provider (is_activating_flag, migrated_to_budapest_flag, organisation_id, application_code, party_id, party_role_type_code) values (?, ?, ?, ?, ?, ?)
2019-01-22 07:17:16,021 DEBUG [main] SQL - update application_dme_provider set application_code=? where application_code=? and party_id=? and party_role_type_code=?
2019-01-22 07:17:16,030 ERROR [main] BatchingBatch - HHH000315: Exception executing batch [java.sql.BatchUpdateException: The UPDATE statement conflicted with the FOREIGN KEY constraint "application_dme_provider_fk1". The conflict occurred in database "ruslans_00_develop_dev_easycare", table "dbo.application", column 'application_code'.], SQL: update application_dme_provider set application_code=? where application_code=? and party_id=? and party_role_type_code=?
2019-01-22 07:17:16,031 ERROR [main] SqlExceptionHelper - The UPDATE statement conflicted with the FOREIGN KEY constraint "application_dme_provider_fk1". The conflict occurred in database "ruslans_00_develop_dev_easycare", table "dbo.application", column 'application_code'.
Organisation class
#Entity(name = "Organisation")
#Table(name = "organisation", uniqueConstraints = {#UniqueConstraint(name = "organisation_name_udx", columnNames = {"name"})})
#NoArgsConstructor
#EntityListeners(EntityCreateListener.class)
public class Organisation implements Serializable, PatientListEntity {
public static final SubscriptionLevel DEFAULT_SUBSCRIPTION_LEVEL = SubscriptionLevel.BASIC;
public static final int NUMBER_OF_DAYS_IN_MONTH = 30;
public static final int MAX_NAME_LENGTH = 50;
public static final int MAX_ACCOUNT_NUMBER_LENGTH = 50;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Getter
#Setter
private Long id;
// Some fields
#Getter
#OneToMany(mappedBy = "organisation", orphanRemoval = true, cascade = CascadeType.ALL)
#MapKeyColumn(name = "application_code")
#JsonManagedReference
private Map<ApplicationEnum, ApplicationDmeProvider> applicationDmeProviderMap = new HashMap<>();
// Some fields
}
ApplicationDmeProvider class
#Entity
#Table(name = "application_dme_provider")
#Getter
#Data
#Builder
#NoArgsConstructor(access = AccessLevel.PROTECTED)
#AllArgsConstructor
#EqualsAndHashCode
public class ApplicationDmeProvider implements Serializable {
#EmbeddedId
private ApplicationDmeProviderId applicationDmeProviderId;
#ManyToOne
#JoinColumn(name = "organisation_id")
#JsonBackReference
private Organisation organisation;
#Type(type = "yes_no")
#Column(name = "migrated_to_budapest_flag")
private boolean migrated;
#Type(type = "yes_no")
#Column(name = "is_activating_flag")
#JsonIgnore
private boolean activating;
}
ApplicationDmeProviderId class
#Data
#NoArgsConstructor
#Embeddable
#AllArgsConstructor
public class ApplicationDmeProviderId implements Serializable {
#Column(name = "application_code")
#Enumerated(EnumType.STRING)
private ApplicationEnum applicationCode;
#JsonBackReference
#Embedded
private PartyRoleId partyRoleId;
}
We checked this test before Hibernate migration and there is no update at all. It looks like Hibernate 5 changed save behavior for this kind of entity.
The problem occurred because of this map applicationDmeProviderMap with ApplicationEnum enum.
The annotation #MapKeyEnumerated(STRING) fixed the problem.

Spring Boot JPA unknown column in field list

In MySQL I have script that create table
create table account (
AccountId int not null auto_increment,
Login varchar(31),
Password varchar(31),
primary key (AccountId)
);
In java class i have model to this table
#Entity
#Table(name = "account")
public class Account {
#Column(name = "AccountId", nullable = false, unique = true)
private Integer AccountId;
private String Login;
private String Password;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getAccountId() {
return AccountId;
}
In Repository package
public interface AccountRepository extends JpaRepository<Account, Integer> {
Account findAccountByLoginAndPassword(String login, String password);
}
In client site i try send in request login and password but i have error in server site
2018-05-28 14:46:15.464 INFO 20300 --- [nio-8080-exec-2] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select account0_.account_id as account_1_0_, account0_.login as login2_0_, account0_.password as password3_0_ from account account0_ where account0_.login=? and account0_.password=?
`ERROR 20300 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'account0_.account_id' in 'field list`
'
That mean I should change my column name in MySQL table to account_id?
"That means I should change my column name in MySQL table to account_id"
Yep, this is a good idea because of naming convention, but also you can configure proper naming strategy:
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
Or you can try to print your column name in lower case. (If your MySQL is Windows based)
#Column(name="accountid", nullable = false, unique = true)
Use #Column(name="accountid", nullable = false, unique = true)
Columns in Mysql are case insensitive. If you use case sensitive column name in #Column then it will convert camel case to snake case.
With Hibernate5 and Spring boot 1.5 or higher, If you still get "unknown column" error even after using PhysicalNamingStrategyStandardImpl as naming strategy, try using #Column mapping on getter method of the field instead of property level #column mapping.

Constraint Violation when persisting One To Many relation

In a spring mvc application using hibernate and MySQL, I am getting the following constraint violation exception:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails
(`mybd`.`hl7_documententity`, CONSTRAINT `hl7_documententity_ibfk_1`
FOREIGN KEY (`ptcode`, `ptcodesystem`)
REFERENCES `hl7_generalcode` (`code`, `codesystem`))
The problem occurs when I try to save a DocumentEntity containing a property of type GeneralCode, both of which are defined below.
I have read many postings and blogs on this error, but none seem to resolve my problem. How can I resolve this error?
Here is the DocumentEntity class:
#Entity
#Table(name = "hl7_documententity")
public class HL7DocumentEntity extends BaseEntity{
//other properties
#ManyToOne
#JoinColumns({ #JoinColumn(name = "ptcode", referencedColumnName = "code"),
#JoinColumn(name = "ptcodesystem", referencedColumnName = "codesystem")
})
private HL7GeneralCode providertype;
//getters and setters
}
Here is the GeneralCode class:
#Entity
#Table(name = "hl7_generalcodes")
public class HL7GeneralCode implements Serializable{
private static final long serialVersionUID = -8620565054475096516L;
#EmbeddedId
private HL7EmbedCodePK codePk;
#OneToMany(mappedBy = "providertype")
private Set<HL7DocumentEntity> documententities;
////////////getters and setters
}
Here is the code from the controller:
HL7GeneralCode authcode = processGeneralCode(grandkid);
HL7GeneralCode testcode = this.clinicService.findGeneralCodeByPK(authcode.getCodePk().getCode(), authcode.getCodePk().getCodesystem());
if(testcode==null){
authcode.addDocumententity(mydent);
this.clinicService.savehl7GeneralCode(authcode);
mydent.setProvidertype(authcode);
//this next line throws the error
this.clinicService.savehl7DocumentEntity(mydent);
}else{
//other stuff
}
Here is the dao method:
#Repository
public class JpaSomethingRepositoryImpl implements SomethingRepository {
#PersistenceContext
private EntityManager em;
#Override
#Transactional
public void savehl7DocumentEntity(HL7DocumentEntity de) {
HL7GeneralCode code = de.getProvidertype();
if(code !=null && code.getCodePk()==null){//HL7GeneralCode is not persistent. We don't support that
throw new IllegalStateException("Cannot persist an adress using a non persistent HL7GeneralCode");
}
System.out.println("=========================== inside jpaCdaRespository.saveDocEntity(de)");
de.setProvidertype(null);
if(code.getDocumententities()!=null){
ArrayList<HL7DocumentEntity> addrList = new ArrayList<HL7DocumentEntity>();
addrList.addAll(code.getDocumententities());
addrList.remove(de);
Set<HL7DocumentEntity> myaddrs = new HashSet<HL7DocumentEntity>(addrList);
code.setDocumententities(myaddrs);
}
code = em.merge(code);
de.setProvidertype(code);
code.addDocumententity(de);
if (de.getId() == null) {
System.out.println("[[[[[[[[[[[[ about to persist de ]]]]]]]]]]]]]]]]]]]]");
em.persist(de);
} else {
System.out.println("]]]]]]]]]]]]]]]]]] about to merge de [[[[[[[[[[[[[[[[[[[[[");
de = em.merge(de);
}
}
}
The executed SQL statement and the actual values that hibernate is trying to insert via the sql are:
[[[[[[[[[[[[ about to persist de ]]]]]]]]]]]]]]]]]]]]
DEBUG SQL - insert into hl7_documententity (author_id, authpar_id, entitytype, id_extension, id_root, ptcode, ptcodesystem, id) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into hl7_documententity (author_id, authpar_id, entitytype, id_extension, id_root, ptcode, ptcodesystem, id) values (?, ?, ?, ?, ?, ?, ?, ?)
TRACE BasicBinder - binding parameter [1] as [INTEGER] - <null>
TRACE BasicBinder - binding parameter [2] as [INTEGER] - <null>
TRACE BasicBinder - binding parameter [3] as [VARCHAR] - <null>
TRACE BasicBinder - binding parameter [4] as [VARCHAR] - NI
TRACE BasicBinder - binding parameter [5] as [VARCHAR] - nullFlavor
TRACE BasicBinder - binding parameter [6] as [VARCHAR] - UNK
TRACE BasicBinder - binding parameter [7] as [VARCHAR] - HL7NullFlavor
TRACE BasicBinder - binding parameter [8] as [INTEGER] - 32787
WARN SqlExceptionHelper - SQL Error: 1452, SQLState: 23000
ERROR SqlExceptionHelper - Cannot add or update a child row: a foreign key constraint fails (`docbd`.`hl7_documententity`, CONSTRAINT `hl7_documententity_ibfk_1` FOREIGN KEY (`ptcode`, `ptcodesystem`) REFERENCES `hl7_generalcode` (`code`, `codesystem`))
INFO AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements
WARN warn - Handler execution resulted in exception
You can read the EmbedCodePK class code by clicking on this link.
You can read the entire stack trace by clicking on this link.
Here is a link to the code for the BaseEntity class.
Change this:
#OneToMany(mappedBy = "providertype")
private Set<HL7DocumentEntity> documententities;
To this:
#OneToMany(fetch = FetchType.LAZY)
#JoinTable(name = "Link_Documents", joinColumns = {#JoinColumn(name = "codePk", unique = true)}, inverseJoinColumns = {#JoinColumn(name = "change_this_with_primary_key_variable_name_from_HL7DocumentEntity")})
private Set<HL7DocumentEntity> documententities;
And in HL7DocumentEntity change as follows:
This
#ManyToOne
#JoinColumns({ #JoinColumn(name = "ptcode", referencedColumnName = "code"),
#JoinColumn(name = "ptcodesystem", referencedColumnName = "codesystem")
})
private HL7GeneralCode providertype;
Change to this:
#ManyToOne(fetch = FetchType.LAZY)
#JoinTable(name = "Link_Documents", joinColumns = {#JoinColumn(name = "change_this_with_primary_key_variable_name_from_HL7DocumentEntity")}, inverseJoinColumns = {#JoinColumn(name = "codePk")})
private HL7GeneralCode providertype;
I think you have to change "change_this_with_primary_key_variable_name_from_HL7DocumentEntity" with "id" like it is in BaseEntity but take a look at your sql table, you willsee there the correct name.
I hope you notice How I told JPA to use the same "Link_Documents" table for linking the 2 tables. I think this is were your mistake is. Just make sure to change where I told you with the correct variable name and I think it should work
you know i would start by cleaning up this code.
Though the hibernate documentation might tell you placing those annotations on the field variables is ok,,, its a bad idea as a standard. field level requires hibernate to create a proxy before the field can be access in the case of lazy fetches. so just get use to doing it correctly and you wont have the misfortune of finding issues. move all those annotations to the getters as property level access doesnt require the proxy.
field level variables should be private.
you are casting an Integer to an Integer in there... some of that stuff makes me not want to look at it and truthfully will probably be a silly bit of laziness that ends up being your problem.
while you are at it go ahead an initialize the set with new HashSet(0); Things like that. Still broken update us.

Categories

Resources