Search code examples
javahibernatetapestry

Tapestry5 Value Encoder with Hibernate Composite Key


I'm trying to get my tapestry value encoder to work with a hibernate composite key. I have the following code and I'm trying to get the composite id and pass it to the interface where it could later be sent back to the server for decoding back to an object.

@Embeddable
public class IfasvVendorPK implements Serializable{

    @Column(length = 4, nullable = false)
    protected String peId;
    @Column(length = 8, nullable = false)
    protected String peAddrCd;

    public IfasvVendorPK() {
    }

    public IfasvVendorPK(String peId, String peAddrCd) {
        this.peId = peId;
        this.peAddrCd = peAddrCd;
    }
    // equals, hashCode
}

@Entity
public class IfasvVendor implements Serializable {

    @EmbeddedId
    private IfasvVendorPK ifasvVendorPK;

    //...
} 

The following is my value encoder. The toClient is where would I need to send the composite key to the interface. I'm not sure how to get the composite key.

@SuppressWarnings("unchecked")
public LabelAwareValueEncoder getEncoderVendor() {
    return new LabelAwareValueEncoder<IfasvVendor>() {

        public String toClient(IfasvVendor value) {
            return value.getIfasvVendorPK().toString();
        }

        public IfasvVendor toValue(String clientValue) {
            if (clientValue.isEmpty()) {
                return null;
            }

            return (IfasvVendor) session.get(IfasvVendor.class, clientValue);
        }

        public String getLabel(IfasvVendor value) {
            return value.getPeNameU();
        }
    };
}  

If someone could help me to better understand how to work with the composite key so I could get my value encoder working, it would be greatly appreciated. Thanks in advance.


Solution

  • Hibernate has no way to know how what this string means and cannot convert it back. I suggest adding a non-composite ID or concaternate the values which you then split again in your toValue method.

    If you keep the ValueEncoder longer than your request (ex. with @Persist) you could put a HashMap in it to easily get the object back for a concaternated client key;

    Since your Composite key is serializeable you could serialize it in toClient and deserialize it in toValue. However, I really wouldn't do that, serializing stuff and sending it to a browser and back is a big, evil security hole.