hibernate не может удалить @Entity с нулевым @Version - PullRequest
1 голос
/ 24 мая 2011

У меня есть JPA @Entity с @Id, определенным как

private UUID id;

@Id
@Column(name = "f_id")
@GeneratedValue(generator = "system-uuid")
@Type(type = "pg-uuid")
public UUID getId() {
    return id;
}

, и полем @Version, определенным как

private Timestamp lastModified;

@Version
@Column(name = "f_lastmodified")
@Attribute(required = false)
public Timestamp getLastModified() {
    return lastModified;
}

результирующий столбец в postgres (сгенерированный hibernate с использованиемcreate-drop) это "метка времени без часового пояса".этот класс используется в приложении, работающем через postgres.при удалении сущности я использую следующий код:

public T delete(UUID id) {
    log.debug("deleting entity {}", id);
    EntityManager em = ... //get from somewhere
    em.flush(); //make sure we're in sync with DB
    T object = em.find(getClassType(), id); //get latest version
    if (object == null) {
        throw new IllegalStateException("could not find an entity with id "+id);
    }
    em.refresh(object);
    em.remove(object);
    em.flush();
    return object;
}

Раньше было проще найти (type, id) + remove, но я добавил дополнительный пух, пытаясь заставить его работать.проблема в том, что приведенный выше код не работает.ошибка, отображаемая в журнале: 08:25:15,940 INFO [STDOUT] Hibernate: 08:25:15,950 INFO [STDOUT] delete 08:25:15,950 INFO [STDOUT] from 08:25:15,950 INFO [STDOUT] dpa.filesystem_status 08:25:15,950 INFO [STDOUT] where 08:25:15,950 INFO [STDOUT] f_id=? 08:25:15,960 INFO [STDOUT] and f_lastmodified=? 08:25:45,123 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session: org.hibernate.StaleObjec tStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [FilesystemStatus#78c839f0-0b12-4df6-b9ec-ac1e52e9b1f1] at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1950) [:3.6.1.Final] at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2710) [:3.6.1.Final] at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2911) [:3.6.1.Final]

после некоторой отладки, я думаю, что я нашел основную причину проблемы: сущность, которую я пытался удалить, имеет NULL в поле версии.hibernate создает подготовленный оператор для удаления (который напечатан в приведенном выше фрагменте журнала), правильно устанавливает идентификатор и затем устанавливает NULL для поля версии (также логически корректно).код hibernate, который делает это, находится в строке 78 BasicBinder.java (ядро hibernate 3.6.1)

st.setNull( index, sqlDescriptor.getSqlType() );

, второй аргумент разрешается до 93 во время выполнения.в конце концов, запуск подготовленного оператора приводит к удалению 0 строк, а спящий режим принимает его, потому что "f_lastmodified =?"part не совпадает и решает, что кто-то должен совершить другую временную метку между ними (== устаревшая сущность передана для удаления).это не правда.

как мне продолжить отсюда?

более конкретно:1. Как я узнаю, что 93 правильный тип sql для передачи в setNull ()?Где я могу найти таблицу "правильных" типов SQL?это специфично для БД (что означает, что я должен посмотреть в postgres docs) или какой-то стандарт JDBC?2. как мне решить проблему?я не могу гарантировать нулевой столбец @Version, поэтому мне нужен этот сценарий для работы3. это известная проблема hibernate / postgresql-jdbc-driver, которую я пропустил?Я использую jdk 1.6u24 x64 на win7 x64, jboss 6.1-snapshot, hibernate 3.6.1.final, postgres 9.0, драйвер postgres jdbc4 9.0-801

1 Ответ

2 голосов
/ 27 мая 2011

Вы не сможете использовать @Version из-за 2-й точки, поскольку столбцы версий должны иметь значение.

2) как мне решить проблему? Я не могу гарантировать нулевой столбец @Version, поэтому мне нужен этот сценарий для работы

Чтобы обойти это, вам нужно либо создать собственное решение для управления версиями, либо вам нужно присвоить этому столбцу значение по умолчанию. Один вопрос, я предполагаю, что строки с нулевыми версиями не генерируются вашим приложением, это правильно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...