Gaël Varlet
Gaël Varlet

Reputation: 1

JPA can't update a date

In my JavaEE App I use JPA to store my datas. But I have a problem with updating a Date stored in database. When I want to change it in my app, (and when I merge), all fields are updating except the date's one... $ Could you help me ?

Here is my Entity :

package persistence
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "NAME")
private String name;
@Column(name = "PLACE")
private String place;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "BEGINDATE")
private Date beginDate;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "ENDDATE")
private Date endDate;
@Column(name = "VISIBILITY")
private int visibility;
@Column(name = "DESCRIPTION")
private String description;

@OneToMany(mappedBy="relatedEvent")
private List<CustomizeEvent> customizedEvents;

@OneToOne(cascade = CascadeType.PERSIST,optional=false)
private Periodicity periodicity;

@ManyToOne(optional=false)
private UserAgenda eventOwner;

@ManyToMany
@JoinTable(name="EVENTS_BELONG_AGENDAS",joinColumns= @JoinColumn(name="EVENT_ID",referencedColumnName="ID"),inverseJoinColumns=@JoinColumn(name="AGENDA_ID",referencedColumnName="ID"))
private List<Agenda> belongToAgendas;

@ManyToMany
@JoinTable(name="EVENTS_GUESTS_AGENDAS",joinColumns= @JoinColumn(name="EVENT_ID",referencedColumnName="ID"),inverseJoinColumns=@JoinColumn(name="AGENDA_ID",referencedColumnName="ID"))    
private List<Agenda> guestToAgendas;

public Event() {
}

public Event(String name, String place, Date beginDate, Date endDate, int visibility, String description, Periodicity periodicity, UserAgenda eventOwner, Agenda agenda) {
    this.name = name;
    this.place = place;
    this.beginDate = beginDate;
    this.endDate = endDate;
    this.visibility = visibility;
    this.description = description;
    this.periodicity = periodicity;
    this.eventOwner = eventOwner;
    this.belongToAgendas = new ArrayList<Agenda>();
    this.belongToAgendas.add(agenda);
    this.customizedEvents = new ArrayList<CustomizeEvent>();
    this.guestToAgendas = new ArrayList<Agenda>();
}

public Event(String name, String place, Date beginDate, Date endDate, int visibility, String description, Periodicity periodicity, UserAgenda eventOwner, Agenda agenda,List<Agenda> guests) {
    this.name = name;
    this.place = place;
    this.beginDate = beginDate;
    this.endDate = endDate;
    this.visibility = visibility;
    this.description = description;
    this.periodicity = periodicity;
    this.eventOwner = eventOwner;
    this.belongToAgendas = new ArrayList<Agenda>();
    this.belongToAgendas.add(agenda);
    this.customizedEvents = new ArrayList<CustomizeEvent>();
    this.guestToAgendas = guests;
}


public Long getId() {
    return id;
}

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

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPlace() {
    return place;
}

public void setPlace(String place) {
    this.place = place;
}

public Date getBeginDate() {
    return beginDate;
}

public void setBeginDate(Date beginDate) {
    this.beginDate = beginDate;
}

public Date getEndDate() {
    return endDate;
}

public void setEndDate(Date endDate) {
    this.endDate = endDate;
}

public int getVisibility() {
    return visibility;
}

public void setVisibility(int visibility) {
    this.visibility = visibility;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public List<CustomizeEvent> getCustomizedEvents() {
    return customizedEvents;
}

public void setCustomizedEvents(List<CustomizeEvent> customizedEvents) {
    this.customizedEvents = customizedEvents;
}

public Periodicity getPeriodicity() {
    return periodicity;
}

public void setPeriodicity(Periodicity periodicity) {
    this.periodicity = periodicity;
}

public UserAgenda getEventOwner() {
    return eventOwner;
}

public void setEventOwner(UserAgenda eventOwner) {
    this.eventOwner = eventOwner;
}

public List<Agenda> getBelongToAgendas() {
    return belongToAgendas;
}

public void setBelongToAgendas(List<Agenda> belongToAgendas) {
    this.belongToAgendas = belongToAgendas;
}

public List<Agenda> getGuestToAgendas() {
    return guestToAgendas;
}

public void setGuestToAgendas(List<Agenda> guestToAgendas) {
    this.guestToAgendas = guestToAgendas;
}





@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Event)) {
        return false;
    }
    Event other = (Event) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "persistence.Event[ id=" + id + " ]";
}

}

and here is my function called in a managed bean :

public void setNewEndDate(Event event, Date endDate) {
    Event e = em.find(Event.class, event.getId());
    e.setEndDate(endDate);
    e.setDescription("New description");
    em.persist(e);
}

Upvotes: 0

Views: 1756

Answers (2)

Sachin Kumar
Sachin Kumar

Reputation: 473

The issue is the same if you have updatable=false on the column that you are trying to update.

Upvotes: 1

Tobb
Tobb

Reputation: 12225

First off, it would be nice with some information with regards to your transaction management, since it's very important with regards to how JPA behaves.

Here is what I think happens:

You have already loaded the Event-object from the EntityManager, and it is probably detached from the session, since you don't get an error when you do EntityManager#find (you can't have 2 objects with the same id in the EntityManager at once, you would get an exception..) So then, you change the state of the just-loaded, attached object, and register it in the EntityManager (I don't think the call to persist is correct, or even necessary here..) But, your detached object (the one sent in as a parameter) is still alive, and it has not been updated with a new value. So, if this object gets reattached and saved at a later point (it might be by you explicitly, or it might happen automatically when the transcation finishes), you will end up overwriting the values set in the method in question.

The method you supply here could (and should) look like this, if anything:

@Transactional
public void setNewDate(final Integer eventId, final Date endDate() {
    final Event e = em.find(Event.class, eventId);
    e.setEndDate(endDate);
    //no need to explicitly save here, the changes will be saved when the transcation ends,
    //and the transaction will only last this method, as indicated by the @Transactional annotation.
}

But still, this is not the proper way to use JPA, usually you have a Repository-layer, which handles basic CRUD operation (find, save, etc), and the a layer on top of that a logic layer, which handles the actual changes to the values in the objects.

Btw, your equals and hashcode methods break the contract for these methods, since id is not always set (a newly created Event-object that has not been persisted will not have an id), and two different, newly created Event-objects that hasn't been stored yet, and thus does not have an id (unless your setting the id yourself, which you really really shouldn't do), will be deemed by the equals method to be identical.

Upvotes: 0

Related Questions