We are migrating application from oracle to Mariadb. Using container transactions and Spring transaction management. I am getting error for code where the one record is saved and updated in same transaction(Service bean method). Same code is working fine for Oracle database.
I am the only one who is connected to the mariadb database. Help will be appreciated.
Error:
org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1JDK: 1.6, Tomcat: 7.0.65, Spring: 4.1, hibernate: 4.2.21
mariadb version: 10.1.13-MariaDB
driver: mariadb-java-client-1.1.9
Dialects: org.hibernate.dialect.MySQLInnoDBDialect
and
i tried with org.hibernate.dialect.MySQLDialect also same error is coming.
Code:
@Entity
@Table(name = "DEAL")
public class Deal implements Serializable {
private static final long serialVersionUID = 1196605299069938794L;
@Id
@Column(name = "SK_DEAL_ID")
@GeneratedValue(strategy = GenerationType.TABLE, generator = "Deal_SEQ")
@TableGenerator(name = "Deal_SEQ", pkColumnValue = "DEAL_SEQUENCE", allocationSize = 1)
@Access(AccessType.PROPERTY)
private Long id;
@Column(name = "INT_DEAL_ID", length = 50)
private String internalDealId;
@Column(name = "DEAL_DESC", length = 100)
private String description;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "LAST_UPDATED_ID")
private SysUser lastUpdatedId;
@Version
@Type(type = "timestamp")
@Column(name = "LAST_UPDATED")
private Date lastUpdated;
@Type(type = "timestamp")
@Column(name = "CREATION_DATE")
private Date creationDate;
@Type(type = "timestamp")
@Column(name = "CREATION_DATE_USER_TZ")
private Date creationDateUserTz;
@Type(type = "date")
@Column(name = "END_DATE")
private Date endDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getInternalDealId() {
return this.internalDealId;
}
public void setInternalDealId(String internalDealId) {
this.internalDealId = internalDealId;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public SysUser getLastUpdatedId() {
return this.lastUpdatedId;
}
public void setLastUpdatedId(SysUser lastUpdatedId) {
this.lastUpdatedId = lastUpdatedId;
}
public Date getLastUpdated() {
return this.lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
public Date getCreationDate() {
return this.creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Date getCreationDateUserTz() {
return creationDateUserTz;
}
public void setCreationDateUserTz(Date creationDateUserTz) {
this.creationDateUserTz = creationDateUserTz;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
@Override
public String toString() {
return new StringBuilder("{")
.append("id=").append(id)
.append(",internalDealId=").append(internalDealId)
.append(",description=").append(description)
.append(",lastUpdatedId=").append(lastUpdatedId != null ? lastUpdatedId.getId() : null)
.append(",lastUpdated=").append(lastUpdated)
.append(",creationDate=").append(creationDate)
.append(",creationDateUserTz=").append(creationDateUserTz)
.append(",endDate=").append(endDate)
.append("}")
.toString();
}
}
Service class method
Code:
@Override
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Transactional(readOnly = false, rollbackFor = Exception.class)
public DealVO addNew(DealVO vo) {
Deal deal = new Deal();
vo.setEndDate(new Date());
deal = convertDealVOToDeal(vo, deal);
dealDao.save(deal);
//Some other logic based on creation date
//setting some other deal properties
dealDao.save(deal);
//original logger is removed as it contains sensitive deal info
vo.setCreationDate(deal.getCreationDate());
vo.setCreationDateUserTz(deal.getCreationDateUserTz());
vo.setId(deal.getId());
return vo;
}
Dao class methods:
Code:
public Session getSession() {
return getSessionFactory().getCurrentSession();
}
@Override
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Transactional(readOnly = false, rollbackFor = Exception.class)
public void save(T domain) {
getSession().saveOrUpdate(domain);
}
Queries generated after control coming out of service method
Code:
insert into DEAL (INT_DEAL_ID, DEAL_DESC, LAST_UPDATED_ID, CREATION_DATE, CREATION_DATE_USER_TZ, END_DATE, SK_DEAL_ID) values (?, ?, ?, ?, ?, ?, ?)
update DEAL set INT_DEAL_ID=?, DEAL_DESC=?, LAST_UPDATED_ID=?, CREATION_DATE=?, CREATION_DATE_USER_TZ=?, END_DATE=? where SK_DEAL_ID=? and LAST_UPDATED=?