I have a many to many relationship that is handled by a join table. Here's the simple
"diagram" :
campaign -> campaign_adslot_xref <- ad_slot
When I create a new campaign object and add adslots to the relationship to get the entries
in the join table created, for some reason, persist is trying to create an entry in the
ad_slot table when the object already exists. Therefore, I get a duplicate key exception.
When I use merge instead of persist, this works fine. I know merge has a bit of overhead
and checking to see if entites exist in the db but my AdSlot object is in the
persistentcontext so I am not sure why it is trying to be created.
The POJO's are:
| @Entity
|
| @Table(name="campaign")
|
| public class ParentCampaign implements Serializable {
| private long id;
|
| private Set<AdSlot> adSlots;
|
| @ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY,
mappedBy="campaigns")
|
| public Set<AdSlot> getAdSlots() {
|
| return adSlots;
|
| }
|
|
|
| public void setAdSlots(Set<AdSlot> adSlots) {
|
| this.adSlots = adSlots;
|
| }
|
| @Override
|
| public int hashCode() {
|
| int hash = 7;
|
| hash = 31 * hash + (int)id;
|
| hash = 31 * hash + ((null == name) ? 0 : name.hashCode());
|
| return hash;
|
| }
|
|
|
| @Override
|
| public boolean equals(Object obj) {
|
| if (obj == this) return true;
|
|
|
| if (null == obj || !(obj instanceof ParentCampaign)) {
|
| return false;
|
| }
|
|
|
| ParentCampaign other = (ParentCampaign)obj;
|
|
|
| if ((id != other.getId())) {
|
| return false;
|
| }
|
|
|
| return true;
|
| }
|
|
| }
|
| @Entity
| @Table(name="ad_slot")
| public class AdSlot implements Serializable {
| private long id;
| private Set<ParentCampaign> campaigns;
|
| @ManyToMany
| @JoinTable(name = "campaign_adslot_xref",
| joinColumns = {
| @JoinColumn(name = "ad_slot_id")
| },
| inverseJoinColumns = {
| @JoinColumn(name = "campaign_id")
| }
| )
|
| public Set<ParentCampaign> getCampaigns()
| {
| return campaigns;
| }
|
| public void setCampaigns(Set<ParentCampaign> campaigns) {
| this.campaigns = campaigns;
| }
|
Here's where I setup the newly created Campaign object with selected AdSlots.
| if (null != selectedAdSlots && selectedAdSlots.length > 0) {
|
| for (int k=0; k < selectedAdSlots.length; k++) {
|
| AdSlot as = Utils.getAdDAO().findAdSlotLazyLoadAll(new
Long(selectedAdSlots[k]));
|
|
|
| if (null == currentCampaign.getAdSlots()) {
|
| currentCampaign.setAdSlots(new HashSet<AdSlot>());
|
| }
|
|
|
| as.getCampaigns().add(currentCampaign);
|
| currentCampaign.getAdSlots().add(as);
|
| }
|
| }
|
|
The findAdSlotLazyLoadAll looks like
| public AdSlot findAdSlotLazyLoadAll(long id) {
|
| return (AdSlot)em.createQuery("FROM AdSlot a " +
|
| "LEFT JOIN FETCH a.program " +
|
| "LEFT JOIN FETCH a.campaigns " +
|
| "WHERE a.id = :id ")
|
| .setParameter("id", id)
|
| .getSingleResult();
|
| }
|
|
|
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3961735#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...