Search code examples
javajpajava-ee-7

JPA thread safe entity


I have entity of item in my system that decelerated like that:

@Entity
@Table(name = "ITEMS")
@XmlRootElement
public class Item implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "ID")
    private Integer id;
    @Column(name = "VIEWS")
    private Integer views;

    // More fields.........

    public Item() {
    }

    public Item(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getViews() {
        return views;
    }

    public void setViews(Integer views) {
        this.views = views;
    }

    // More getters and setters.......
}

In my system each user can view the item, but only the owner can edit it. The only limitation is that the owner can edit the item only if no one else view it yet.

So my update method should look like that:

public void update(Integer id) {
    Item item = itemFacade.find(id);
    if (item == null || item.getViews() > 0) {
        return;
    }

    // Set some fields......

    itemFacade.edit(item);
}

This method must be synchronized because there is a race condition: When I sets the fields, other user viewed the item.

But how can I protect against that race condition? I think that I was read somewhere that JPA creates new instances of the entities when it finds them. So making synchronized(item) (after I check that it is not null) can't protect against that race condition, because the lockers are different.

So how can I prevent such race condition?


Solution

  • The correct answer to solve conflicts described here.