2015-07-01 1 views
0

В приложении JSF (Primefaces) У меня есть следующий объект:Объединения снятой JPA объекта сохраняет его обратно в базу данных

@Entity 
@Table(name = "shop_tree") 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = "itemType", discriminatorType =  DiscriminatorType.STRING) 
@NamedQuery(name = "selectSorted", query = "SELECT t FROM ShopTree t  ORDER BY t.parentId ASC, t.position ASC") 
public abstract class ShopTree implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
    @NotNull 
    private Long parentId; 
    @NotNull 
    private Integer position = 0; 
    @NotNull 
    private String name; 
    private String seoLinkName; 
    @Enumerated(EnumType.STRING) 
    @Column(name = "itemType", insertable = false, updatable = false) 
    @NotNull 
    private TreeItemType itemType = TreeItemType.SPACER; 
    private boolean released; 
    private int importError; 
    private boolean seoRelevant; 
    @Version 
    @Column(name = "version", nullable = false) 
    private long version = 0l; 

И эти два метода в соответствующем классе фасадного (A @Stateless фасоль):

Существует около 6 специальных типов, которые наследуются от этого базового класса, все они содержат только 1 или 2 основных атрибута, таких как дополнительные int, long или string - на самом деле ничего особенного.

Пример:

@Entity 
@DiscriminatorValue(TreeItemType.Values.FREE_LINK) 
public class Freelink extends ShopTree { 

    private String freeLink; 

    public Freelink() { 
    super(); 
    this.setItemType(TreeItemType.FREE_LINK); 
    } 

    // Getter /Setter 
} 

Поскольку объекты образуют довольно сложную структуру дерева я прочитал их в память (с помощью именованного запроса) и сохранить их в сессии. Теперь, когда пользователь за один сеанс удаляет элемент, а другой пользователь редактирует один из удаленных объектов, объект просто сохраняется в базе данных снова - без каких-либо исключений. Он получает новый идентификатор, как и я использовал persist вместо merge.

Как это может быть? Не должно быть исключения?

Все удаления и слияния выполняются с помощью вышеуказанных методов, нет абсолютно никаких исключений.

Есть ли способ предотвратить, чтобы jpa снова сохранил удаленный объект в базе данных. Я хотел бы получать информацию от JPA, что юридическое лицо, я просто пытаюсь

Я использую

  • wildfly 8.2.0-финал (что означает спящий режим 4.3.1, я думаю, и
  • Java 8
  • Java EE 7 апи
  • JSF 2,2
+0

Что вы используете для разграничения транзакций? «OptimisticLockException» не будет выбрасываться до тех пор, пока транзакция не совершит –

+0

Используются ли пользователи с одним и тем же «сеансом» или каждый пользователь имеет свой «сеанс»? Если это последний, то сущности значительно отделяются, а это означает, что каждая копия объекта является отдельным экземпляром. Имеет ли объединенный объект (сохраненный вторым пользователем) идентификатор, когда он сохраняется? Кроме того, почему вы инициализируете 'версию'? Я никогда не видел этого раньше, и это выглядит неправильно. Мы никогда не делали этого ни в одной из 400-странных сущностей, которые мы используем. Обычно базовый поставщик обеспечения сохранности выполняет инициализацию поля версии. – DuncanKinnear

+0

@SteveC ничего особенного, контейнер управляет транзакциями для меня. У меня нет каких-либо явных атрибутов транзакции или аннотации для любого метода или класса. – Lasrik

ответ

0

Если вы используете метод merge без существования проверки вы Assum что вы являетесь единственным, кто удерживает данные в этот момент, слияние выполняет проверку сеанса, но сущность не находится в сеансе, потому что это сообщение формы, поэтому оно пытается извлечь из базы данных, но уже удалено (delete завершено) sot он помечает объект как новый (тогда commit создает инструкцию insert).

Если вы знаете, что другие пользователи могут изменять или удалять те же объекты, что вам нужно выполнить проверку наличия вручную перед слиянием, или использовать поведение блокировки для блокировки одновременных изменений тех же объектов.