mercredi 1 juillet 2015

Merging a removed jpa entity saves it back to database

In an JSF (Primefaces) application I have the following entity:

@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;

And these two methods in the corresponding facade class (a @Stateless bean):

public T merge(T entity) throws ConcurrentUpdateException {
    try {
      return getEntityManager().merge(entity);
    } catch (OptimisticLockException ex) {
      log.warn("OptimisticLocking Exception: ex.getEntity() {} -     entity {}", ex.getEntity().getClass().getName(), entity);
      throw new ConcurrentUpdateException(entity);
    }
  }

  public void remove(T entity) {
    getEntityManager().remove(getEntityManager().merge(entity));
  }

There are about 6 special types that inherit from this base class, all of them just contain 1 or 2 more basic attributes like additional int, long or string - really nothing special.

Example:

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

  private String freeLink;

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

  // Getter /Setter
}

Since the entities form a somewhat complex tree structure I read them into memory (via the named query) and keep them in session. Now when a user in one session deletes an item and another user edits one of the deleted entities, the entity is simply stored in database again - without any exception. It gets a new id just like I used persist instead of merge.

How can that be? Shouldn't there be an exception?

All deletion and merge is done via the above methods, there is absolutely no exception.

Is there any way I prevent jpa from saving the removed entity to database again. I would like to be informed by JPA that the entity I just try to

I am using

  • wildfly 8.2.0-final (which means hibernate 4.3.1 I think and
  • java 8
  • Java ee 7 api
  • JSF 2.2

Aucun commentaire:

Enregistrer un commentaire