Parent is product entity, and child is stock entity distinguished by time(like a hotel stock model that the stock of every booking day should be different and manipulated separately)
The ProductEntity
is defined as:
@Entity
@Table(name = "product")
public class ProductEntity{
....
private long productId;
private List<StockEntity> stockEntityList;
....
@Id
@Column(name="productId")
public long getProductId(){
return this.productId;
}
@OneToMany(mappedBy="productEntity", fetch= FetchType.EAGER
cascade={CascadeType.ALL,CascadeType.PERSIST,CascadeType.MERGE},
orphanRemoval = true)
public List<StockEntity> getStockEntityList(){
return this.stockEnityList;
}
public void setStockEntityList(List<StockEntity> stockEntityList){...}
....
}
And the StockEntity
is defined as:
@Entity
@Table(name = "stock")
public class StockEntity{
...
private ProductEntity productEntity;
private long startTime;
...
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="productId")
public ProductEntity getProductEntity(){
return this.producntEntity;
}
@Id
@Column(name="startTime")
public long getStartTime(){
return this.startTime;
}
....
}
Since you are aware, I use productId of ProductEntity
as a foreign key and the startTime
(a long type time-stamp) as a primary key.
Then I want to update a specific stock item of the product by:
public void consumeStockQuantity(long productId, long startTime, int count){
Session session = HBSession.getSession();
Transaction tx = session.beginTransaction();
ProductEntity productEntity = session.get(productId, ProductEntity.class);
for(StockEntity stockEntity: productEntity.getStockEntityList()){
if(stockEntity.getStartTime() == startTime){
stockEntity.setQuantity(stockEntity.getQuantity-count);
}
}
try{
session.update(productEntity);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}finally{
session.close();
}
}
With above DAO code, I expect to modify the stock amount of specific stock item(identified by startTime
) of specific product.
But some times I will got a update count mis-match with expected error
when there are stock items with same startTime
and different product id, I triggered the hibernate log and find that, in the sql generated by hibernate, the update SQL only contains the startTime
(which is explicit as a @Id
) but no productId
in the query condition:
Hibernate:
update
test.stock
set
marketPrice=?,
productId=?,
purchasePrice=?,
quantity=?,
sellPrice=?
where
startTime=? //here missing productId which is a joinedColumn
HibernateLog --> 15:35:27 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [FLOAT] - [1.2]
HibernateLog --> 15:35:27 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [BIGINT] - [1075]
HibernateLog --> 15:35:27 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [FLOAT] - [0.01]
HibernateLog --> 15:35:27 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [4] as [BIGINT] - [1000]
HibernateLog --> 15:35:27 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [5] as [FLOAT] - [0.01]
HibernateLog --> 15:35:27 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [6] as [BIGINT] - [1438175312412]
Exception in thread "main" org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 2; expected: 1
So, How to solve this?