Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Composite Primary key error - Multiple writable mappings exist for the field
Composite Primary key error - Multiple writable mappings exist for the field [message #1104560] Sun, 08 September 2013 15:41 Go to next message
n n is currently offline n n
Messages: 2
Registered: September 2013
Junior Member
hello, have simple example code

@Entity
@Table(name = "item_author_role")
public class ItemAuthorRole implements Serializable {
  @Getter @Setter @EmbeddedId
  private ItemAuthorRoleId id;
  @Setter private Item item;

  @MapsId("itemId")
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "item_id", referencedColumnName = "item_id")
  public Item getItem()               { return item; }
 
 @Override
  public boolean equals(Object obj) {
    if(obj instanceof ItemAuthorRole) {
      ItemAuthorRole role = (ItemAuthorRole) obj;
      return role.getItem().equals(item);
    }
    return false;

  }

  @Override
  public int hashCode() {
    return new HashCodeBuilder(17, 31).append(item).toHashCode();
  }
}

@Embeddable
class ItemAuthorRoleId implements Serializable {
  @Getter @Setter @Column(name = "item_id", nullable = false)
  private int itemId;

  @Override
  public boolean equals(Object obj) {
    if(obj instanceof ItemAuthorRoleId) {
      ItemAuthorRoleId id = (ItemAuthorRoleId) obj;
      return id.itemId == itemId;
    }
    return false;

  }
  @Override
  public int hashCode() {
    return new HashCodeBuilder(17, 31).append(itemId).toHashCode();
  }
}


Item

@Entity
@Table(name = "items")
public class Item extends AbstractModel implements Serializable {
  @Setter private Set<ItemAuthorRole> itemAuthorRoleSet;
  @Setter private Technic technic;

  {
    itemAuthorRoleSet = new HashSet<>(0);
  }

  @Override
  @SequenceGenerator(name = "isg", sequenceName = "item_sequence", initialValue = 1, allocationSize = 2)

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "isg")
  public Integer getId()                               { return super.getId(); }

  @JoinColumn(name = "item_id", insertable = false, updatable = false) //no effect 
  @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH}, mappedBy = "item", targetEntity = ItemAuthorRole.class)
  public Set<ItemAuthorRole> getItemAuthorRoleSet()    { return itemAuthorRoleSet; }

  @OneToOne
  @JoinColumn(name = "technic_id")
  public Technic getTechnic()                          { return technic; }

  @Version
  @Column(name = "opt_lock")
  private Long version;
}


Exception [EclipseLink-48] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [item_author_role.item_id].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[item]
Descriptor: RelationalDescriptor(model.item.ItemAuthorRole --> [DatabaseTable(item_author_role)])



i seen this link http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/mappedbyid
but i don`t understand what wrong in my example, thanks

[Updated on: Mon, 09 September 2013 03:28]

Report message to a moderator

Re: Composite Primary key error - Multiple writable mappings exist for the field [message #1105205 is a reply to message #1104560] Mon, 09 September 2013 14:04 Go to previous messageGo to next message
Chris Delahunt is currently online Chris Delahunt
Messages: 1026
Registered: July 2009
Senior Member
Why are you using a join column on the OneToMany instead of marking it as mappedBy? Remove the @JoinColumn annotation from Item and be sure to rebuild your app.

It also looks like you are putting JPA annotations on both fields and methods. Try moving the ItemAuthorRole's getItem annotations to the item attribute, as this might be causing them to be not read. If that doesn't help, turn logging onto finest and post the annotation processing that occurs for the ItemAuthorRole entity during JPA deployment.

Best Regards,
Chris
Re: Composite Primary key error - Multiple writable mappings exist for the field [message #1105271 is a reply to message #1105205] Mon, 09 September 2013 16:01 Go to previous messageGo to next message
n n is currently offline n n
Messages: 2
Registered: September 2013
Junior Member
>Remove the @JoinColumn annotation from Item and be sure to rebuild your app
that already tried, the same error

>It also looks like you are putting JPA annotations on both fields and methods
why ? jpa annotations only on method, on field only @Setter annotation
  @Setter private Item item;

  @MapsId("itemId")
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "item_id", referencedColumnName = "item_id")
  public Item getItem()               { return item; }


but in this case it work,
  @MapsId("itemId")
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "item_id", referencedColumnName = "item_id")
  @Setter @Getter private Item item;


or this
  @MapsId("itemId")
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "item_id", referencedColumnName = "item_id")
  @Setter private Item item;

  public Item getItem()               { return item; }


maybe it`s bug of @Setter @Getter annotations library
thanks for help!
Re: Composite Primary key error - Multiple writable mappings exist for the field [message #1106015 is a reply to message #1105271] Tue, 10 September 2013 15:14 Go to previous message
Chris Delahunt is currently online Chris Delahunt
Messages: 1026
Registered: July 2009
Senior Member
JPA annotations must all be on the fields, or all on methods, as it is used to define the access type for the entity. In this case, you have annotations on the ItemAuthorRole id field (@Embeddable) which causes JPA to use field access and ignore the method annotations. This causes the defaults for item to be used, which is to use an "ITEM_ID" foreign key field.

Keeping all JPA annotations on fields allows your MapsId, JoinColumn and ManyToOne to be picked up and is just good practice unless there is a need for JPA to access certain fields differently. If there is, the @Access annotation allows setting the AccessType for the entity and overriding it on mappings, allowing you to specify AccessType.property on getItem() while keeping AccessType.field access on the id.

Best Regards,
Chris
Previous Topic:@CacheIndex doesn't work with Criteria Query
Next Topic:Typed query hints
Goto Forum:
  


Current Time: Wed Oct 01 04:15:07 GMT 2014

Powered by FUDForum. Page generated in 0.03851 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software