Столбец rowversion / timestamp в SqlServer является глобальным счетчиком, который увеличивается при каждой вставке и обновлении.
Проблема:
После вставки или обновления свойство гибернации, сопоставленное столбцу версии строк, не обновляется автоматически.
Я хотел бы, чтобы это происходило автоматически = без извлечения этого столбца (или вся модель) после сброса, в каждом месте, где выполняется обновление или вставка.
Мое решение:
На данный момент я попытался извлечь этот столбец сразу после обновления - он не работает если грипп sh происходит не сразу после обновления.
SQL Таблица:
CREATE TABLE [dbo].[Example](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[description] [varchar](250) NOT NULL,
[rowversion] [timestamp] NOT NULL,
CONSTRAINT [PK_Example] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Модель гибернации:
@Entity
@Table(name = "Example")
public class ExampleRow implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private long id;
@Column(name = "name", nullable = false, length = 50)
private String name;
@Column(name = "description", nullable = false, length = 250)
private String description;
@Column(name = "rowversion", insertable = false, updatable = false)
private byte[] rowVersion;
/* getters & setters */
}
Java:
private ExampleRow fetchFromDataBase(long id) {
Query<ExampleRow> query = getCurrentSession().createQuery(
"select row from ExampleRow row where row.id = :id",
ExampleRow.class);
query.setParameter("id", id);
List<ExampleRow> list = query.list();
ExampleRow singleRowFromDataBase = list.get(0);
return singleRowFromDataBase;
}
private void printRV(ExampleRow singleRowFromDataBase) {
for(int i = 0; i < singleRowFromDataBase.getRowVersion().length; i++) {
System.out.println(i + " => " + singleRowFromDataBase.getRowVersion()[i]);
}
}
public ExampleRow edit(long id, String name, String description) {
ExampleRow singleRowFromDataBase = fetchFromDataBase(id);
singleRowFromDataBase.setName(name);
singleRowFromDataBase.setDescription(description);
// RV before edit
printRV(singleRowFromDataBase);
getCurrentSession().merge(singleRowFromDataBase);
// RV after edit (if flush is set to manual, the rowVersion is still the same - the query is not ran on database yet)
ExampleRow singleRowFromDataBaseBeforeFlush = fetchFromDataBase(id);
printRV(singleRowFromDataBaseBeforeFlush);
getCurrentSession().flush();
// RV after edit & flush - is updated
ExampleRow singleRowFromDataBaseAfterFlush = fetchFromDataBase(id);
printRV(singleRowFromDataBaseAfterFlush);
// Replace RV value or simply return fresh instance from database...
singleRowFromDataBase.setRowVersion(singleRowFromDataBaseAfterFlush.getRowVersion());
return singleRowFromDataBase;
}