سؤال

I have three classes as following:

import java.sql.Timestamp;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Type;


@Entity

public class EventTO {

...
private List<EventAssignedResourceTO> eventAssignedResourceTOList;


/**
 * @return the eventAssignedResourceTOList
 */
@OneToMany(fetch = FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "EAR_EVN_ID")
public List<EventAssignedResourceTO> getEventAssignedResourceTOList() {
    return eventAssignedResourceTOList;
}

/**
 * @param eventAssignedResourceTOList
 *            the eventAssignedResourceTOList to set
 */
public void setEventAssignedResourceTOList(List<EventAssignedResourceTO>   eventAssignedResourceTOList) {
    this.eventAssignedResourceTOList = eventAssignedResourceTOList;
}

public void setPrivate(boolean aPrivate) {
    setPrivateEvent(aPrivate);
}

}

The second class:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;


@Entity
public class EventAssignedResourceTO  {

private EventTO eventTO;
private EventResourceTO eventResourceTO;
private int resourceCount;


/**
 * @return the eventTO
 */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EAR_EVN_ID", updatable = false, insertable=false, nullable = false)
public EventTO getEventTO() {
    return eventTO;
}

/**
 * @param eventTO
 *            the eventTO to set
 */
public void setEventTO(EventTO eventTO) {
    this.eventTO = eventTO;
}


/**
 * @return the eventResourceId
 */
@Transient
public Long getEventResourceId() {
    return eventResourceId;
}

/**
 * @param eventResourceId
 *            the eventResourceId to set
 */
public void setEventResourceId(Long eventResourceId) {
    this.eventResourceId = eventResourceId;
}

/**
 * @return the resourceCount
 */
@Column(name = "EAR_COUNT")
public int getResourceCount() {
    return resourceCount;
}

/**
 * @param resourceCount
 *            the resourceCount to set
 */
public void setResourceCount(int resourceCount) {
    this.resourceCount = resourceCount;
}

/**
 * @return the eventResourceTO
 */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EAR_ERS_ID")
public EventResourceTO getEventResourceTO() {
    return eventResourceTO;
}

/**
 * @param eventResourceTO
 *            the eventResourceTO to set
 */
public void setEventResourceTO(EventResourceTO eventResourceTO) {
    this.eventResourceTO = eventResourceTO;
}
}

The third class:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.hibernate.annotations.Type;


@Entity
public class EventResourceTO {
private String name;
private int count;
private boolean active;

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
@Column(name = "ERS_ID")
public Long getId() {
    return super.getId();
}

/**
 * @return the name
 */
@Column(name="ERS_NAME")
public String getName() {
    return name;
}

/**
 * @param name
 *            the name to set
 */
public void setName(String name) {
    this.name = name;
}

/**
 * @return the count
 */
@Column(name="ERS_COUNT")
public int getCount() {
    return count;
}

/**
 * @param count
 *            the count to set
 */
public void setCount(int count) {
    this.count = count;
}

/**
 * @return the active
 */
@Type(type="yes_no")
@Column(name="ERS_IS_ACTIVE")
public boolean isActive() {
    return active;
}

/**
 * @param active
 *            the active to set
 */
public void setActive(boolean active) {
    this.active = active;
}

}

I have followed the official hibernate documentation here: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#collections-bidirectional

and this example here: http://viralpatel.net/blogs/hibernate-one-to-many-annotation-tutorial/

The problem is that while inserting the EventTO in DB I get a constraint violation on the eventId because hibernate cannot set the id of newly created event in the eventTO in EventAssignedResourceTO and the id is null .

So I decided to remove the updatable and insertable tag in the JoinColumn annotation in the EventAssignedResourceTO.

Now the insert works properly but when I want to delete an Event, hibernate deletes the AssignedResourceTO first then the event and at the end I don't know why it tries to update the record of AssignedResourceTO in its table. Here it tries to set the id of eventTO to NULL and I get constraint violation. the same also occurs for update.

I'm really confused since what is written in the official documentation does not work and I was unable to find any solution on the web.

any idea??

Cheers

هل كانت مفيدة؟

المحلول

You don't need @JoinColumn(name = "EAR_EVN_ID") in EventTO class. Instead add mappedBy to the association. So:

@OneToMany(mappedBy = "eventTO", fetch = FetchType.LAZY,cascade=CascadeType.ALL)
public List<EventAssignedResourceTO> getEventAssignedResourceTOList() {
    return eventAssignedResourceTOList;
}

Also fetch is by default LAZY for @OneToMany associations, you can remove that too.

نصائح أخرى

for bidirectional mapping use JoinColumn annotation only at Parent and use mappedBy property in child .and for removing recurrence between parent and child entity use these annotations.

@OneToMany(
            mappedBy = "queue_group",fetch = FetchType.LAZY,
            cascade = CascadeType.ALL
        )
    @JsonManagedReference
    private Set<Queue> queues;

 @ManyToOne(cascade=CascadeType.ALL)
        @JoinColumn(name = "qid")
       // @JsonIgnore
        @JsonBackReference
        private Queue_group queue_group;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top