У меня есть класс, который имеет следующие поля:JPA: какой-либо полный пример использования @Version для предотвращения одновременных изменений в одной записи?
@Version
private Long version = 1L;
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
Я использую Spring Web + Hibernate. Я надеюсь увидеть относительно полный пример использования @Version для предотвращения одновременных изменений в одной записи.
Поиск в Google и поиск SO. Не удалось найти какой-либо. Я использовал поле скрытой формы HTML для поля версии, и оно не работает.
Любая информация/указатель действительно оценена.
Спасибо и приветствую!
Update 1
Вот что я сделал. Я загрузил одну и ту же запись в два окна браузера. Я смог увидеть, что в HTML-форме обоих окон есть скрытое поле версии с тем же значением. Я отправил форму в одно окно и проверил базу данных и заметил, что поле «Версия» было увеличено. Затем я представил другое окно. Ничего не произошло, и запись была успешно обновлена / сохранена. Я ожидал, что какое-то исключение было брошено.
Нужно ли настраивать комбинацию весна/спящий режим, чтобы она работала, помимо определения поля Версии?
Update 2
я сделал следующее, чтобы проследить, как Hibernate обновить запись:
hibernate.show_sql=true
log4j.logger.org.hibernate.type=trace
Теперь я могу видеть, как Hibernate обновить запись. Я заметил, что в момент Hibernate обновления записи с помощью следующего SQL
update ... where id=? and version=?
Hibernate всегда использует номер последней версии из базы данных, чтобы связать, хотя я могу подтвердить, что в веб-слой записи по-прежнему имеет старый номер версии плюс другие поля с новыми данными перед сохранением записи.
Почему?
Я чувствую, что оптимистическая блокировка как-то отключена в моем приложении, но для этого я не могу использовать конфигурацию Hibernate. Я использую Hibernate 4.2.1.Final и Spring 3.2.2.RELEASE.
Есть ли способ явного включения/отключения блокировки спящего режима спящего режима?
Обновление 3
Ниже приводится объекты данных и уровень базы данных кода. «friendGroupDao» автоматически подключается к уровню транзакционных услуг, где этот объект DAO вызывается для загрузки объекта на веб-уровень и сохраняет объект в базе данных. Связанные методы уровня обслуживания просто вызывают friendGroupDao.load() и friendGroupDao.save() без какого-либо дополнительного кода.
-------------- объекты домена -------------
@MappedSuperclass
public abstract class BaseObject implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Version
private Long version = 1L;
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public BaseObject() {
}
}
@Entity
public class FriendGroup extends BaseObject {
@Column(columnDefinition = "NVARCHAR(120)")
private String name;
public String getName() {
return name;
}
public void setName(String accountName) {
this.name = accountName;
}
}
--------------- database -------------
public interface BaseObjectDao<T extends BaseObject> {
void delete(T o);
T load(Long id);
void save(T o);
}
public class BaseObjectDaoImpl<T extends BaseObject> implements
BaseObjectDao<T> {
private Class<T> domainClass;
@Autowired
protected SessionFactory sessionFactory;
public BaseObjectDaoImpl() {
this.domainClass = (Class<T>) BaseObject.class;
}
public BaseObjectDaoImpl(Class<T> domainClass) {
this.domainClass = domainClass;
}
public SessionFactory getSessFactory() {
return sessionFactory;
}
public void setSessFactory(SessionFactory sf) {
this.sessionFactory = sf;
}
public void delete(T object) {
getSession().delete(object);
}
public T load(Long id) {
return (T) getSession().get(domainClass, id);
}
public void save(T object) {
getSession().saveOrUpdate(object);
}
public Session getSession() {
return sessionFactory.getCurrentSession();
}
}
public interface FriendGroupDao extends BaseObjectDao<FriendGroup> {
}
@Repository("friendGroupDao")
public class FriendGroupDaoImpl extends BaseObjectDaoImpl<FriendGroup> implements
FriendGroupDao {
public FriendGroupDaoImpl() {
super(FriendGroup.class);
}
}
Что вы подразумеваете под словом «Это не работает»? Что вы ожидаете и что происходит? – andih
Есть несколько вопросов или ответов, относящихся к аннотации '@ Version'. Например http://stackoverflow.com/questions/1838646/jpa-version-how-to-use-it или http://stackoverflow.com/questions/2572566/java-jpa-version-annotation – andih
andih, я читаю первое сообщение до моего поста. Вторая статья полезна. Возможно, именно поэтому я сделал этот пост. Я не уверен, как это работает. – curious1