JPA #MapsId inserts 0 instead of correct value - java

I have these entities (unnecessary columns removed for brevity)
Order
#Entity
#Table(name = "orders")
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#OneToOne(mappedBy = "order", cascade = CascadeType.ALL, optional = false)
private Shipment shipment;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Shipment getShipment() {
return shipment;
}
public void setShipment(Shipment shipment) {
this.shipment = shipment;
this.shipment.setOrder(this);
}
}
Shipment
#Entity
#Table(name = "shipments")
public class Shipment {
#Id
#Column(name = "order_id")
private int id;
#OneToOne
#MapsId
private Order order;
#OneToOne(mappedBy = "shipment", cascade = CascadeType.ALL, optional = false)
private ShippingAddress shippingAddress;
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public ShippingAddress getShippingAddress() {
return shippingAddress;
}
public void setShippingAddress(ShippingAddress shippingAddress) {
this.shippingAddress = shippingAddress;
this.shippingAddress.setShipment(this);
}
}
ShippingAddress
#Entity
#Table(name = "shipping_address")
public class ShippingAddress {
#Id
#Column(name = "shipment_id")
private int id;
#OneToOne
#MapsId("shipment_id")
private Shipment shipment;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Shipment getShipment() {
return shipment;
}
public void setShipment(Shipment shipment) {
this.shipment = shipment;
}
}
The problem arises when I attempt to save a new Order. As you can see from the logs, Hibernate correctly sets the values to the Order and Shipment entities but assigns 0 to the shipment_id column in shipping_address, which of course causes a FK conflict.
I believe I'm using #MapsId correctly, because like I said, it works for the Order and Shipment relationship, but it doesn't seem to work for the Shipment and ShippingAddress.
These are the logs
2021-01-14 14:25:56,563 DEBUG [http-nio-8080-exec-3] org.hibernate.SQL: insert into orders (branch_office, coupon_code, customer_id, external_id, increment_id, interests, origin_channel, store_id, subtotal, total, total_discount, total_qty_ordered) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2021-01-14 14:25:56,564 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [1] as [VARCHAR] - [null]
2021-01-14 14:25:56,564 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [2] as [VARCHAR] - [null]
2021-01-14 14:25:56,564 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [3] as [INTEGER] - [20]
2021-01-14 14:25:56,564 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [4] as [VARCHAR] - [5501505642]
2021-01-14 14:25:56,564 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [5] as [VARCHAR] - [5501505642]
2021-01-14 14:25:56,564 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [6] as [NUMERIC] - [0.0000]
2021-01-14 14:25:56,565 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [7] as [VARCHAR] - [store]
2021-01-14 14:25:56,565 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [8] as [INTEGER] - [55]
2021-01-14 14:25:56,565 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [9] as [NUMERIC] - [2270.0000]
2021-01-14 14:25:56,565 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [10] as [NUMERIC] - [1580]
2021-01-14 14:25:56,565 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [11] as [NUMERIC] - [690]
2021-01-14 14:25:56,565 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [12] as [INTEGER] - [3]
2021-01-14 14:25:56,621 DEBUG [http-nio-8080-exec-3] org.hibernate.SQL: insert into shipments (carrier_id, pickup_id, shipment_id, shipping_cost, order_id) values (?, ?, ?, ?, ?)
2021-01-14 14:25:56,621 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [1] as [INTEGER] - [19]
2021-01-14 14:25:56,622 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [2] as [INTEGER] - [19]
2021-01-14 14:25:56,622 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [3] as [INTEGER] - [null]
2021-01-14 14:25:56,622 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [4] as [NUMERIC] - [0.0]
2021-01-14 14:25:56,622 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [5] as [INTEGER] - [20]
2021-01-14 14:25:56,623 DEBUG [http-nio-8080-exec-3] org.hibernate.SQL: insert into shipping_address (city, country_code, province_id, street_name, street_number, zip_code, shipment_id) values (?, ?, ?, ?, ?, ?, ?)
2021-01-14 14:25:56,624 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [1] as [VARCHAR] - [Vicente López]
2021-01-14 14:25:56,624 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [2] as [VARCHAR] - [AR]
2021-01-14 14:25:56,624 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [3] as [INTEGER] - [21]
2021-01-14 14:25:56,624 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [4] as [VARCHAR] - [ramon melgar,Nro 8170]
2021-01-14 14:25:56,624 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [5] as [VARCHAR] - []
2021-01-14 14:25:56,624 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [6] as [VARCHAR] - [1638]
2021-01-14 14:25:56,624 TRACE [http-nio-8080-exec-3] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [7] as [INTEGER] - [0]
As you can see on the last insert, Hibernate attempts to insert a 0 instead of the shipment_id.
Is there something I'm missing?

According to the documentation the value of the #MapsId annotation is referred to the name of the attribute within the composite key to which the relationship attribute corresponds. You do not use composite key.
So, this:
#OneToOne
#MapsId("shipment_id")
private Shipment shipment;
should be corrected to this:
#OneToOne
#MapsId
#JoinColumn(name = "shipment_id")
private Shipment shipment;
I can not find proof in the documentation, but hibernate ignore #Column(name = "shipment_id") on #Id when you use #MapsId, so you should specify PK column name of the ShippingAddress by adding #JoinColumn.

Related

Is hibernate executing additional update while persisting using #Convert annotation?

When I'm trying to save a simple entity in hibernate with field marked with #Convert annotation insert is always followed by update with the same parameters as in insert.
Entity to save
#Entity
public class Building {
#Id
#GeneratedValue
private Long id;
#Convert(converter = AddressConverter.class)
private Address address;
...
Object that is converted to String
public class Address {
private String street;
private String city;
...
Converter
#Converter
class AddressConverter implements AttributeConverter<Address, String> {
#Override
public String convertToDatabaseColumn(Address attribute) {
return attribute.getStreet() + " " + attribute.getCity();
}
#Override
public Address convertToEntityAttribute(String dbData) {
String[] data = dbData.split(" ");
Address address = new Address();
address.setStreet(data[0]);
address.setCity(data[1]);
return address;
}
}
It should work like that, and if it should, why? I don't see at first glance any reason to make this additional query.
Logs looks like this:
18:52:14.959 [main] DEBUG org.hibernate.SQL - insert into building (address, id) values (?, ?)
18:52:14.960 [main] TRACE org.hibernate.orm.jdbc.bind - binding parameter [1] as [VARCHAR] - [test-street test-city]
18:52:14.961 [main] TRACE org.hibernate.orm.jdbc.bind - binding parameter [2] as [BIGINT] - [1]
18:52:14.962 [main] DEBUG org.hibernate.SQL - update building set address=? where id=?
18:52:14.964 [main] TRACE org.hibernate.orm.jdbc.bind - binding parameter [1] as [VARCHAR] - [test-street test-city]
18:52:14.964 [main] TRACE org.hibernate.orm.jdbc.bind - binding parameter [2] as [BIGINT] - [1]
I've made proof, so you can check it here: https://gitlab.com/Piterowsky/demo-insert-update-convert-annotation/-/tree/master/src/main/java/com/example/demo

Hibernate JPA - Wrongly generated insert statement

Hibernate is generating wrong insert statement - wrong column binding - for the following entity model with single table inheritance and composite primary key using #IdClass.
Wondering if this is a Hibernate bug.
Stack: Spring Boot 2.7 / H2
Superclass base entity - AbstractMemberEvent:
#Entity
#Table(name = "MEMBER_EVENTS")
#Getter
#FieldDefaults(level = AccessLevel.PRIVATE)
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "EVENT_TYPE")
#NoArgsConstructor
#IdClass(MemberEventId.class)
public abstract class AbstractMemberEvent {
#Id
#Column(name = "USID")
String usid;
#Id
#Column(name = "UPDATED")
Long eventTime;
#Id
#Column(name = "EVENT_TYPE", insertable = false, updatable = false )
String eventType;
Subclass entity - NewMemberJoined
#Entity
#Getter
#Setter
#FieldDefaults(level = AccessLevel.PRIVATE)
#DiscriminatorValue("NEWMEMBERJOINED")
#NoArgsConstructor
public class NewMemberJoined extends AbstractMemberEvent{
#Column(name="PAYLOAD")
NewMemberJoinedInfo newMemberJoinedInfo;
The IdClass
#Getter
#FieldDefaults(level = AccessLevel.PRIVATE)
#NoArgsConstructor
#EqualsAndHashCode
public class MemberEventId implements Serializable {
String usid;
Long eventTime;
String eventType;
}
From the logs I see that the wrong values are bound to the parameters
Hibernate:
create table member_events (
event_type varchar(31) not null,
updated bigint not null,
usid varchar(255) not null,
payload varchar(255),
primary key (updated, event_type, usid)
)
...
Hibernate:
insert
into
member_events
(payload, event_type, updated, usid)
values
(?, ?, ?, ?)
2022-11-25 21:52:13.789 DEBUG 527088 --- [ restartedMain] tributeConverterSqlTypeDescriptorAdapter : Converted value on binding : ...
2022-11-25 21:52:13.790 TRACE 527088 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [{"firstName":"Jasper" ...}]
2022-11-25 21:52:13.790 TRACE 527088 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [1388534400000]
2022-11-25 21:52:13.790 TRACE 527088 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [NEWMEMBERJOINED]
2022-11-25 21:52:13.790 TRACE 527088 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [3060001234567]
2022-11-25 21:52:13.794 WARN 527088 --- [ restartedMain] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 22018, SQLState: 22018
2022-11-25 21:52:13.794 ERROR 527088 --- [ restartedMain] o.h.engine.jdbc.spi.SqlExceptionHelper : Data conversion error converting "'NEWMEMBERJOINED' (MEMBER_EVENTS: ""UPDATED"" BIGINT NOT NULL)"; SQL statement:
insert into member_events (payload, event_type, updated, usid) values (?, ?, ?, ?) [22018-214]7'

Instead of update query , calling insert query in spring jpa

I am trying to update multiple table in spring jpa.
Consumer table update is happening perfectl but provider table is not able to update. Instead of it , its trying for insert which causes violation of primary key which is expected because it is trying for insert instead of update.
Although my code flow for both the table is same but there is issue only with producer.
This is my Consumer entity
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
#Data
#Entity
#Table(name = "consumer_table")
#IdClass(ConsumerId.class)
public class Consumer implements Serializable {
#Id
#Column(name = "consumer_cmdb")
private String consumerCMDB;
#Id
#Column(name = "api_name")
private String apiName;
#Column(name = "consumer_app_vp")
private String consumerAppVp;
#Column(name = "consumer_app_director")
private String consumerAppDirector;
#Column(name = "consumer_app_manager")
private String consumerAppManager;
#Column(name = "consumer_tps")
private String consumerTps;
#Column(name = "consumer_hosted_on")
private String consumerHost;
#Column(name = "consumer_system_type")
private String consumerSystemType;
#Column(name = "carbon_namespace_ownership")
private String consumerCarbonNamespaceOwnership;
#Column(name = "hosted_vm_ownership")
private String consumerHostedVmOwnership;
#Column(name = "consumer_status")
private String consumerStatus;
#Column(name = "comments")
private String ConsumerComments;
#Column(name = "consumer_auth_type")
private String ConsumerAuthType;
}
This is my Consumer repository
import java.util.List;
#Repository
public interface ConsumerRepository extends JpaRepository<Consumer, ConsumerId> {
List<Consumer> findByConsumerCMDB(String CMDB);
#Query(nativeQuery = true,value = "select count(*) from consumer_table where api_name IS NOT NULL AND consumer_cmdb=:cmdbId")
Integer getTotalApisOwned(#Param("cmdbId") String cmdbId);
List<Consumer> findByApiName(String apiName);
Consumer findByApiNameAndConsumerCMDB(String apiName,String consumerCMDB);
}
This is my Provider entity
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
#Data
#Entity
#Table(name = "provider_table")
#IdClass(Provider.class)
public class Provider implements Serializable {
#Id
#Column(name = "api_name")
private String apiName;
#Id
#Column(name = "provider_cmdb")
private String providerCMDB;
#Column(name = "provider_app_vp")
private String providerAppVp;
#Column(name = "provider_app_director")
private String providerAppDirector;
#Column(name = "upstream_service_hosted_on")
private String upstreamServiceHost;
#Column(name = "upstream_service_url")
private String upstreamServiceUrl;
#Column(name = "upstream_vm_ownership")
private String upstreamVmOwnership;
#Column(name = "upstream_service_type")
private String upstreamServiceType;
#Column(name = "carbon_namespace_ownership")
private String providerCarbonNamespaceOwnership;
#Column(name = "hosted_vm_ownership")
private String providerHostedVmOwnership;
#Column(name = "provider_status")
private String providerStatus;
#Column(name = "comments")
private String providerComments;
}
This is my Provider Repository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface ProviderRepository extends JpaRepository<Provider, ProviderId> {
public List<Provider> findByApiName(String apiName);
public Provider findByUpstreamServiceUrl(String upstreamUrl);
public Provider findByApiNameAndProviderCMDB(String apiName,String providerCMDB);
/* #Query()
public void updateProviderByCMDBAndApiName(Provider provider, String providerCMDB, String apiName);*/
}
Here is the logs
2022-07-13 21:13:25.442 DEBUG [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] org.hibernate.SQL : select consumer0_.api_name as api_name1_1_0_, consumer0_.consumer_cmdb as consumer2_1_0_, consumer0_.consumer_auth_type as consumer3_1_0_, consumer0_.comments as comments4_1_0_, consumer0_.consumer_app_director as consumer5_1_0_, consumer0_.consumer_app_manager as consumer6_1_0_, consumer0_.consumer_app_vp as consumer7_1_0_, consumer0_.carbon_namespace_ownership as carbon_n8_1_0_, consumer0_.consumer_hosted_on as consumer9_1_0_, consumer0_.hosted_vm_ownership as hosted_10_1_0_, consumer0_.consumer_status as consume11_1_0_, consumer0_.consumer_system_type as consume12_1_0_, consumer0_.consumer_tps as consume13_1_0_ from consumer_table consumer0_ where consumer0_.api_name=? and consumer0_.consumer_cmdb=?
Hibernate: select consumer0_.api_name as api_name1_1_0_, consumer0_.consumer_cmdb as consumer2_1_0_, consumer0_.consumer_auth_type as consumer3_1_0_, consumer0_.comments as comments4_1_0_, consumer0_.consumer_app_director as consumer5_1_0_, consumer0_.consumer_app_manager as consumer6_1_0_, consumer0_.consumer_app_vp as consumer7_1_0_, consumer0_.carbon_namespace_ownership as carbon_n8_1_0_, consumer0_.consumer_hosted_on as consumer9_1_0_, consumer0_.hosted_vm_ownership as hosted_10_1_0_, consumer0_.consumer_status as consume11_1_0_, consumer0_.consumer_system_type as consume12_1_0_, consumer0_.consumer_tps as consume13_1_0_ from consumer_table consumer0_ where consumer0_.api_name=? and consumer0_.consumer_cmdb=?
2022-07-13 21:13:25.444 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [a1]
2022-07-13 21:13:25.445 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [cm1]
2022-07-13 21:13:25.811 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([api_name1_1_0_] : [VARCHAR]) - [a1]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consumer2_1_0_] : [VARCHAR]) - [cm1]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consumer3_1_0_] : [VARCHAR]) - [cat4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([comments4_1_0_] : [VARCHAR]) - [cm4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consumer5_1_0_] : [VARCHAR]) - [cd4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consumer6_1_0_] : [VARCHAR]) - [capm4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consumer7_1_0_] : [VARCHAR]) - [cap4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([carbon_n8_1_0_] : [VARCHAR]) - []
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consumer9_1_0_] : [VARCHAR]) - [ch4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([hosted_10_1_0_] : [VARCHAR]) - [chvm4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consume11_1_0_] : [VARCHAR]) - [cs4]
2022-07-13 21:13:25.812 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consume12_1_0_] : [VARCHAR]) - [cst4]
2022-07-13 21:13:25.813 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicExtractor : extracted value ([consume13_1_0_] : [VARCHAR]) - [null]
2022-07-13 21:13:25.818 DEBUG [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] org.hibernate.SQL : update consumer_table set consumer_auth_type=?, comments=?, consumer_app_director=?, consumer_app_manager=?, consumer_app_vp=?, carbon_namespace_ownership=?, consumer_hosted_on=?, hosted_vm_ownership=?, consumer_status=?, consumer_system_type=?, consumer_tps=? where api_name=? and consumer_cmdb=?
Hibernate: update consumer_table set consumer_auth_type=?, comments=?, consumer_app_director=?, consumer_app_manager=?, consumer_app_vp=?, carbon_namespace_ownership=?, consumer_hosted_on=?, hosted_vm_ownership=?, consumer_status=?, consumer_system_type=?, consumer_tps=? where api_name=? and consumer_cmdb=?
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [cat4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [cm5]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [cd4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [capm4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [VARCHAR] - [cap4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [VARCHAR] - []
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [7] as [VARCHAR] - [ch4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [8] as [VARCHAR] - [chvm4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [9] as [VARCHAR] - [cs4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [10] as [VARCHAR] - [cst4]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [11] as [VARCHAR] - [null]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [12] as [VARCHAR] - [a1]
2022-07-13 21:13:25.819 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [13] as [VARCHAR] - [cm1]
2022-07-13 21:13:26.533 DEBUG [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] org.hibernate.SQL : select provider0_.provider_cmdb as provider1_2_0_, provider0_.api_name as api_name2_2_0_, provider0_.provider_app_director as provider3_2_0_, provider0_.provider_app_vp as provider4_2_0_, provider0_.carbon_namespace_ownership as carbon_n5_2_0_, provider0_.comments as comments6_2_0_, provider0_.hosted_vm_ownership as hosted_v7_2_0_, provider0_.provider_status as provider8_2_0_, provider0_.upstream_service_hosted_on as upstream9_2_0_, provider0_.upstream_service_type as upstrea10_2_0_, provider0_.upstream_service_url as upstrea11_2_0_, provider0_.upstream_vm_ownership as upstrea12_2_0_ from provider_table provider0_ where provider0_.provider_cmdb=? and provider0_.api_name=? and provider0_.provider_app_director=? and provider0_.provider_app_vp=? and provider0_.carbon_namespace_ownership=? and provider0_.comments=? and provider0_.hosted_vm_ownership=? and provider0_.provider_status=? and provider0_.upstream_service_hosted_on=? and provider0_.upstream_service_type=? and provider0_.upstream_service_url=? and provider0_.upstream_vm_ownership=?
Hibernate: select provider0_.provider_cmdb as provider1_2_0_, provider0_.api_name as api_name2_2_0_, provider0_.provider_app_director as provider3_2_0_, provider0_.provider_app_vp as provider4_2_0_, provider0_.carbon_namespace_ownership as carbon_n5_2_0_, provider0_.comments as comments6_2_0_, provider0_.hosted_vm_ownership as hosted_v7_2_0_, provider0_.provider_status as provider8_2_0_, provider0_.upstream_service_hosted_on as upstream9_2_0_, provider0_.upstream_service_type as upstrea10_2_0_, provider0_.upstream_service_url as upstrea11_2_0_, provider0_.upstream_vm_ownership as upstrea12_2_0_ from provider_table provider0_ where provider0_.provider_cmdb=? and provider0_.api_name=? and provider0_.provider_app_director=? and provider0_.provider_app_vp=? and provider0_.carbon_namespace_ownership=? and provider0_.comments=? and provider0_.hosted_vm_ownership=? and provider0_.provider_status=? and provider0_.upstream_service_hosted_on=? and provider0_.upstream_service_type=? and provider0_.upstream_service_url=? and provider0_.upstream_vm_ownership=?
2022-07-13 21:13:26.534 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [pcm1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [a1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [p1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [p1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [VARCHAR] - [p1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [VARCHAR] - [pc5]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [7] as [VARCHAR] - [pw1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [8] as [VARCHAR] - [ps1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [9] as [VARCHAR] - [uh1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [10] as [VARCHAR] - [us1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [11] as [VARCHAR] - [us1]
2022-07-13 21:13:26.535 TRACE [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [12] as [VARCHAR] - [uo1]
2022-07-13 21:13:26.900 DEBUG [,ae80adb706f0a62d,ae80adb706f0a62d] 53825 --- [nio-8431-exec-3] org.hibernate.SQL : insert into provider_table (provider_cmdb, api_name, provider_app_director, provider_app_vp, carbon_namespace_ownership, comments, hosted_vm_ownership, provider_status, upstream_service_hosted_on, upstream_service_type, upstream_service_url, upstream_vm_ownership) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into provider_table (provider_cmdb, api_name, provider_app_director, provider_app_vp, carbon_namespace_ownership, comments, hosted_vm_ownership, provider_status, upstream_service_hosted_on, upstream_service_type, upstream_service_url, upstream_vm_ownership) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
As the service layer isn't given based on the question i would like to answer,considering providerRepository object is present
Provider provider=providerRepository.findByUpstreamServiceUrl("xyz"); //Assuming using this method
provider.setXYZ(..);///set the values needed to be updated
providerRepository.save(provider); // As JPA works on state of an object this would update the object instead in inserting in DB
As ID of Object is present in DB instead of inserting new it will merge by calling save method
Refer:How do I update an entity using spring-data-jpa?
#Modifying annotation is used to enhance the #Query annotation so that we can execute not only SELECT queries, also insert, update, delete, and even DDL queries.
For more detail go through this link.
You can also use #Modifying and #Query to write your custom JPA query
to update the Provider table.
#Modifying
#Query("your custom JPQL update query")
What you can also do is get the previous provider entity/data you want to update and do the changes in the same data and again save it.
I got the issue.Actually in Provider class , I was annotating with wrong class. I have made the changes and now It's working fine :)
Here is the latest Provider entity class
#Data
#Entity
#Table(name = "provider_table")
#IdClass(ProviderId.class)
public class Provider implements Serializable {
#Id
#Column(name = "api_name")
private String apiName;
#Id
#Column(name = "provider_cmdb")
private String providerCMDB;
#Column(name = "provider_app_vp")
private String providerAppVp;
#Column(name = "provider_app_director")
private String providerAppDirector;
#Column(name = "upstream_service_hosted_on")
private String upstreamServiceHost;
#Column(name = "upstream_service_url")
private String upstreamServiceUrl;
#Column(name = "upstream_vm_ownership")
private String upstreamVmOwnership;
#Column(name = "upstream_service_type")
private String upstreamServiceType;
#Column(name = "carbon_namespace_ownership")
private String providerCarbonNamespaceOwnership;
#Column(name = "hosted_vm_ownership")
private String providerHostedVmOwnership;
#Column(name = "provider_status")
private String providerStatus;
#Column(name = "comments")
private String providerComments;
}

Error of "Duplicate entry '14' for key 'dishes.PRIMARY'" When saving a value in DB via Json file

I have a problem saving a row in the "Orders" table. Each order includes a list of dishes.
When I saved through the code everything was fine. But when I send a JSON file, I see that Spring sends an update command to the DISH table. And I do not understand why, how can he be made not to update the value obtained?
this is the orders class:
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name="Orders")
public class Orders {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int orderId;
#Column(name="customer_name")
private String customerName;
#ElementCollection
#ManyToMany(mappedBy ="Orders",cascade = CascadeType.MERGE)
#JoinColumn(name = "id")
private List<Dish> dish;
#Column(name="order_date")
private Date orderDate;
#Enumerated(value = EnumType.ORDINAL)
#Column(name = "status_id")
private Status status;
#Enumerated(value = EnumType.ORDINAL)
#Column(name = "table_id")
private RTable table;
#ManyToOne
#JoinColumn(name = "waiter_id")
private Waiter waiter;
#Column(name="total_price")
private double totalPrice;
The Dish class:
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name="dishes")
public class Dish{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
#Column(name="preperation_Time_By_Minutes")
private double preperationTimeByMinutes;
private double price;
}
part from the trace: (including the unwanted update query)
Hibernate: insert into orders (customer_name, order_date, status_id, table_id, total_price, waiter_id) values (?, ?, ?, ?, ?, ?)
2022-05-23 16:05:20.398 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [null]
2022-05-23 16:05:20.398 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [TIMESTAMP] - [Sun Nov 05 02:00:00 IST 2023]
2022-05-23 16:05:20.398 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [INTEGER] - [1]
2022-05-23 16:05:20.398 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [INTEGER] - [2]
2022-05-23 16:05:20.399 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [DOUBLE] - [0.0]
2022-05-23 16:05:20.399 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [INTEGER] - [null]
2022-05-23 16:05:20.404 DEBUG 19712 --- [nio-8080-exec-6] org.hibernate.SQL : update dishes set id=? where id=?
Hibernate: update dishes set id=? where id=?
2022-05-23 16:05:20.404 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [14]
2022-05-23 16:05:20.405 TRACE 19712 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [1]
2022-05-23 16:05:20.406 WARN 19712 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1062, SQLState: 23000
2022-05-23 16:05:20.406 ERROR 19712 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : Duplicate entry '14' for key 'dishes.PRIMARY'
2022-05-23 16:05:20.406 INFO 19712 --- [nio-8080-exec-6] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2022-05-23 16:05:20.409 ERROR 19712 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [dishes.PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '14' for key 'dishes.PRIMARY'
....
......
.........

Hibernate Creating Or Updating Entity triggers update on related (Child) Entity

Whenever I update UserEntity hibernate triggers an update on the related UserRoles table. I found similar issues here but could not find a working solution.
#Entity
#Table(name = "users")
#AllArgsConstructor
#NoArgsConstructor
#Builder
public class UserEntity implements Serializable {
#Id
#GeneratedValue(strategy = AUTO)
private UUID uuid;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
private String email;
#JsonIgnore private String password;
#JsonIgnore
#OneToMany(mappedBy = "user", fetch = LAZY, cascade = REMOVE)
#Builder.Default
private List<UserRoleEntity> roles = new ArrayList<>();
#Entity
#Table(name = "user_roles")
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#EntityListeners(AuditingEntityListener.class)
#TypeDef(name = "enum_postgres_sql", typeClass = PostgresEnumType.class)
public class UserRoleEntity {
#Id
#GeneratedValue(strategy = AUTO)
private UUID uuid;
#Column(name = "role")
#Enumerated(STRING)
#Type(type = "enum_postgres_sql")
private Role role;
#ManyToOne
#JoinColumn(name = "user_uuid", updatable = false)
private UserEntity user;
#Type(
type = "com.vladmihalcea.hibernate.type.array.ListArrayType",
parameters = {#Parameter(name = ListArrayType.SQL_ARRAY_TYPE, value = "permission")})
#Column(name = "permissions", columnDefinition = "permission[]")
#Builder.Default
private List<Permission> permissions = new ArrayList<>();
#CreatedBy #OneToOne private UserEntity createdBy;
#LastModifiedBy #OneToOne private UserEntity lastModifiedBy;
}
Create user:
UserEntity user =
UserEntity.builder()
.firstName(dto.getFirstName())
.lastName(dto.getLastName())
.email(dto.getEmail())
.createdAt(LocalDateTime.now())
.build();
repository.save(user);
Update user:
repository
.findById(uuid)
.ifPresentOrElse(
e -> {
e.setFirstName(dto.getFirstName());
e.setLastName(dto.getLastName());
if (!StringUtils.equals(dto.getEmail(), e.getEmail())) {
e.setEmail(dto.getEmail());
}
e.setUpdatedAt(LocalDateTime.now());
repository.save(e);
},
() -> {
LOGGER.error("UserEntity with uuid: {} not found", uuid);
throw new UserEntityNotFoundException(uuid);
});
Repo
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<UserEntity, UUID> {}
Does anyone have an idea how to prevent this?
The reason I want to prevent this is that I'm using triggers in Postgresql to write logs of user actions and unnecessary updates mess things up... :(
Here are some logs:
2021-07-07 01:17:04,748 INFO o.s.d.r.c.DeferredRepositoryInitializationListener:53 - Spring Data repositories initialized!
2021-07-07 01:17:04,768 INFO c.s.j.l.u.w.UserLogControllerGetCreatedUserIntegrationTest:61 - Started UserLogControllerGetCreatedUserIntegrationTest in 36.711 seconds (JVM running for 39.424)
2021-07-07 01:17:04,936 DEBUG c.s.j.t.m.DatabaseMixin:31 - TestContainers database properties: test#jdbc:postgresql://localhost:56611/test?loggerLevel=OFF
2021-07-07 01:17:05,112 DEBUG o.h.SQL:128 -
insert
into
users
(changed_by_uuid, company_uuid, created_at, email, first_name, last_name, password, status, type, updated_at, uuid)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2021-07-07 01:17:05,115 TRACE o.h.t.d.s.BasicBinder:52 - binding parameter [1] as [OTHER] - [null]
2021-07-07 01:17:05,115 TRACE o.h.t.d.s.BasicBinder:52 - binding parameter [2] as [OTHER] - [null]
2021-07-07 01:17:05,116 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [3] as [TIMESTAMP] - [2021-07-07T01:17:05.104298]
2021-07-07 01:17:05,117 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [4] as [VARCHAR] - [new#test.com]
2021-07-07 01:17:05,117 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [5] as [VARCHAR] - [John]
2021-07-07 01:17:05,118 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [6] as [VARCHAR] - [Doe]
2021-07-07 01:17:05,118 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [7] as [VARCHAR] - [$2a$10$woVXWhuoHEqoIZMlul6/4.cc.33AyTCUc8nDWDiqImuj0vqlY.PK.]
2021-07-07 01:17:05,118 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [10] as [TIMESTAMP] - [2021-07-07T01:17:05.104346]
2021-07-07 01:17:05,119 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [11] as [OTHER] - [4df92c40-fde1-4a09-bfe9-53f2deb2f41d]
2021-07-07 01:17:05,140 DEBUG o.h.SQL:128 -
insert
into
user_roles
(changed_by_uuid, permissions, role, user_uuid, uuid)
values
(?, ?, ?, ?, ?)
2021-07-07 01:17:05,140 TRACE o.h.t.d.s.BasicBinder:52 - binding parameter [1] as [OTHER] - [null]
2021-07-07 01:17:05,141 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [2] as [ARRAY] - [[Ljava.lang.Object;#24be7cee]
2021-07-07 01:17:05,152 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [4] as [OTHER] - [4df92c40-fde1-4a09-bfe9-53f2deb2f41d]
2021-07-07 01:17:05,153 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [5] as [OTHER] - [2fa664b9-f9cd-4092-a38b-c46d47c0ab95]
2021-07-07 01:17:05,156 DEBUG o.h.SQL:128 -
update
user_roles
set
changed_by_uuid=?,
permissions=?,
role=?,
user_uuid=?
where
uuid=?
2021-07-07 01:17:05,156 TRACE o.h.t.d.s.BasicBinder:52 - binding parameter [1] as [OTHER] - [null]
2021-07-07 01:17:05,157 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [2] as [ARRAY] - [[CREATE]]
2021-07-07 01:17:05,157 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [4] as [OTHER] - [4df92c40-fde1-4a09-bfe9-53f2deb2f41d]
2021-07-07 01:17:05,157 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [5] as [OTHER] - [2fa664b9-f9cd-4092-a38b-c46d47c0ab95]
2021-07-07 01:17:05,165 DEBUG o.h.SQL:128 -
insert
into
user_roles
(changed_by_uuid, permissions, role, user_uuid, uuid)
values
(?, ?, ?, ?, ?)
2021-07-07 01:17:05,165 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [1] as [OTHER] - [4df92c40-fde1-4a09-bfe9-53f2deb2f41d]
2021-07-07 01:17:05,165 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [2] as [ARRAY] - [[Ljava.lang.Object;#4bc4b33b]
2021-07-07 01:17:05,166 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [4] as [OTHER] - [4df92c40-fde1-4a09-bfe9-53f2deb2f41d]
2021-07-07 01:17:05,166 TRACE o.h.t.d.s.BasicBinder:64 - binding parameter [5] as [OTHER] - [afe1ed15-005f-4c2e-8d55-bd3db570dc2e]
2021-07-07 01:17:05,168 DEBUG o.h.SQL:128 -
update
user_roles
set
changed_by_uuid=?,
permissions=?,
role=?,
user_uuid=?
where
uuid=?
Actually, it is a bug in the Hibernate: HHH-5855
I used List instead of Set in many-to-many
The permissions were mapped badly
This is the way it should look
permissions column is mutable and Hibernate flushes again because it can't determine dirtiness
The solution was:
#Type(
type = "com.vladmihalcea.hibernate.type.array.EnumArrayType",
parameters = {#Parameter(name = EnumArrayType.SQL_ARRAY_TYPE, value = "permission")})
#Column(name = "permissions", columnDefinition = "permission[]")
private Permission[] permissions;

Categories