1 Reply Latest reply on Dec 20, 2006 8:08 PM by Daniel Young

    MapKey, JoinColumn and referencedColumnName

    Daniel Young Novice

      Hi all,

      I'm trying to use a map-based relationship on a non-PK, provided below. The EJB3 spec states that "when used for relationship mappings, the referenced column is in the table of the target entity".

      However, when I do this, I get "Unable to find column with logical name" errors from Ejb3JoinColumn.java when deploying.

      To get around this, I tried swapping the values of the "name" and "referencedColumnName" attributes in my JoinColumn annotation. The relationship then works perfectly fine for reading and updating, but when I go to delete entities that have such a relationship (and cascade ALL), the operation fails with the following:

      org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of Organisation.brandMessageId
       at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
       at org.hibernate.tuple.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:58)
       at org.hibernate.tuple.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:64)
       at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:76)
       at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:307)
       at org.hibernate.type.ComponentType.nullSafeGetValues(ComponentType.java:280)
       at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:235)
       at org.hibernate.persister.collection.AbstractCollectionPersister.writeKey(AbstractCollectionPersister.java:723)
       at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1010)
       at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:28)
      


      I debugged using the source and found that it was trying to reference Long.getBrandMessageId() instead of Organisation.getBrandMessageId()!!

      Here is the relevant portion of my mapping. I've provided it in the way that works except for deletes (but seems to go against the EJB3 spec). To see the other way, just swap msg_id and brand_msg id for the name and referencedColumnName.
       @Column(nullable = true, name = "brand_msg_id")
       public Long getBrandMessageId() {
       return brandMessageId;
       }
      
       public void setBrandMessageId(final Long brandMessageId) {
       this.brandMessageId = brandMessageId;
       }
      
       @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
       @JoinColumn(name = "msg_id", referencedColumnName = "brand_msg_id")
       @MapKey(name = "locale")
       public Map<String, Message> getBrandMap() {
       return brandMap;
       }
      
       public void setBrandMap(final Map<String, Message> brand) {
       this.brandMap = brand;
       }
      


      My tables are:
      Organisation.id (PK)
      Organisation.brand_msg_id
      
      Message.id (PK)
      Message.msg_id
      Message.locale
      Message.message
      


      I've browsed Jira and found some issues with JoinColumn and Map relationships, but nothing that really looks like this.

      So, my questions are:
      1) is the check that Ejb3JoinColumn.java does going against what is written in the EJB3 spec?
      2) if not, should I have name="msg_id", referencedColumnName="brand_msg_id" above?
      3) if so, what is happening when it tries to cascade deletes to the messages Map but gives the error shown above?

      thanks in advance,
      Daniel.