Reputation: 3690
I am recreating the database using -
spring.jpa.hibernate.ddl-auto=create
( am using a spring boot jpa project).
So hibernate is droping the earlier tables and recreating new one's as expected. In this post, to distinguish
hibernate output
and
java code
i am using above convention.
Hibernate is querying and tyring to alter existing schema as below -
alter table state
drop
foreign key FKcdpxn6x9xj5h0r44m8poebva0
... and so on
drop table if exists state
and after droping the constrains and the tables - it's recreating the tables and constrains..
2019-09-08 13:14:05.794 DEBUG 5016 --- [ restartedMain] org.hibernate.SQL :
create table state (
name varchar(255) not null,
population varchar(255),
country_name varchar(255),
primary key (name)
)
... creating few more tables and then the constraints...
2019-09-08 13:14:08.355 DEBUG 5016 --- [ restartedMain] org.hibernate.SQL :
alter table state
add constraint FKcdpxn6x9xj5h0r44m8poebva0
foreign key (country_name)
references country (name)
so far so good... next there is an insert operation in java code...
Country usa = new Country ("USA", "330000000"); countryRepository.save(usa);
my problem is here. Prior to inserting, hibernate is doing a select statement...
2019-09-08 13:14:10.915 DEBUG 5016 --- [ restartedMain] org.hibernate.SQL :
select
country0_.name as name1_1_1_,
country0_.population as populati2_1_1_,
states1_.country_name as country_3_2_3_,
states1_.name as name1_2_3_,
states1_.name as name1_2_0_,
states1_.country_name as country_3_2_0_,
states1_.population as populati2_2_0_
from
country country0_
left outer join
state states1_
on country0_.name=states1_.country_name
where
country0_.name=?
2019-09-08 13:14:10.915 TRACE 5016 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [USA]
Next Hibernate is doing the actual insert...
2019-09-08 13:14:11.552 DEBUG 5016 --- [ restartedMain] org.hibernate.SQL :
insert
into
country
(population, name)
values
(?, ?)
2019-09-08 13:14:11.553 TRACE 5016 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [330000000]
So, am wondering what is the purpose of querying the tables prior to inserting.
Update/Edit - as asked on comments, java model code is below.
@Table(name="state")
@Entity
public class State {
@Id
@Column(name="name")
String name;
@Column(name="population")
String population;
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="state_name")
List<City> cities;
@ManyToOne (cascade=CascadeType.ALL, fetch=FetchType.LAZY)
Country country;
getters / setters
@Table(name="country")
@Entity
public class Country {
@Id
@Column(name="name")
String name;
@Column(name="population")
String population;
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="country_name")
List<State> states;
getters/setters
Upvotes: 1
Views: 1210
Reputation: 502
Hibernate does that because you specified the value of the primary key (which is in your case the country name), So this behavior helps hibernate to determine what action to do, i.e insert a new record, or update an existing record
To avoid this behavior, you can use the optimistic locking by adding the @javax.persistence.Version
to your entity, like this:
@Table(name="country")
@Entity
public class Country {
@Id
@Column(name="name")
String name;
@Version
Integer version;
@Column(name="population")
String population;
The first time you create the record and prior to inserting it into DB, the value of the version will be null.
If the version value is null, so hibernate marks the record as new and insert statement will be executed, otherwise and if it has a value, that means it's an existing record, and update statement will be executed
Upvotes: 1