Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Mapping Compound PK with FK Reference?(How does one map an entity with a compound primary key that has a foreign key in it in EclipseLink?)
Mapping Compound PK with FK Reference? [message #757174] Wed, 16 November 2011 23:13 Go to next message
Shelli Orton is currently offline Shelli Orton
Messages: 76
Registered: September 2009
Member
Hi,

I've been trying to figure out how to map a compound primary key part of which is a foreign key to a parent table. This is what the tables look like:
----------       ----------
Parent           Child  
----------       ----------
name(PK)         name(PK)
string1          parent_name(PK, FK)
                 string1


My Parent class looks like this:
@Entity
@Table(name = "PARENT")
public class Parent
{
    private String name;
    private Set<Child> children;
    private String string1;

    public Parent()
    {
        // empty constructor
    }

    @Id
    @Column(name = "NAME")
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name= name;
    }

    // bi-directional many-to-one association to Child
    @OneToMany(mappedBy = "parent")
    public Set<Child> getChildren()
    {
        return children;
    }

    public void setChildren(Set<Child> children)
    {
        this.children= children;
    }

    @Column(name = "STRING1")
    public String getString1()
    {
        return string1;
    }

    public void setString1(String string1)
    {
        this.string1 = string1;
    }
}


What I'm having problems with is the Child and ChildPK classes. If all the fields of the child primary key weren't part of a foreign key, I would set them up like this:

@Entity
public class Child
{
    private ChildPK childId;
    private String string1;

    public Child()
    {
        // empty constructor
    }

    @EmbeddedId
    public ChildPK getChildId()
    {
        return childId;
    }

    public void setChildId(ChildPK childId)
    {
        this.childId= childId;
    }


    @Column(name = "STRING1")
    public String getString1()
    {
        return string1;
    }

    public void setString1(String string1)
    {
        this.string1 = string1;
    }
}

@Embeddable
public class ChildPK implements Serializable
{
    private static final long serialVersionUID = 1L;
    private String name;
    private String parentName;

    public ChildPK()
    {
        //empty
    }
    

    @Column(name = "NAME")
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name= name;
    }

    @Column(name = "PARENT_NAME")
    public String getParentName()
    {
        return parentName;
    }

    public void setParentName(String parentName)
    {
        this.parentName= parentName;
    }
}


But this set up doesn't allow for the Child to reference it's Parent object.
I tried setting it up IAW the example in the "Pro EJB 3 Java Persistence API" book by Keith and Schincariol in which the ChildPK class is not Embeddable and the fields aren't annotated with Column. The Child class would be set up like this:

@Entity
@IdClass(ChildPK.class)
public class Child
{
    private String name;
    private String parentName;
    private Parent parent;
    private String string1;

    public Child()
    {
        // empty constructor
    }

    @Id
    @Column(name = "NAME")
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name= name;
    }

    @Id
    @Column(name = "PARENT_NAME")
    public String getParentName()
    {
        return parentName;
    }

    public void setParentName(String parentName)
    {
        this.parentName= parentName;
    }

    @ManyToOne
    @JoinColumn(name = "PARENT_NAME")
    public Parent getParent()
    {
        return parent;
    }

    public void setParent(Parent parent)
    {
        this.parent= parent;
    }

    @Column(name = "STRING1")
    public String getString1()
    {
        return string1;
    }

    public void setString1(String string1)
    {
        this.string1 = string1;
    }
}


The book notes that not all JPA implentations may support this and this seems to be the case with EclipseLink as it won't deploy in Glassfish (v3.1.1) with this error:

Error occurred during deployment: Exception while preparing the app : Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.EntityManagerSetupException Exception Description: Predeployment of PersistenceUnit [myUnit] failed. Internal Exception: Exception [EclipseLink-7233] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.ValidationException Exception Description: Mapping metadata cannot be applied to properties/methods that take arguments. The attribute [method setParentName] from class [class my.company.Child] is in violation of this restriction. Ensure the method has no arguments if it is mapped with annotations or in an XML mapping file.. Please see server.log for more details. 


How does one map an entity with a compound primary key that has a foreign key in it in EclipseLink?
Re: Mapping Compound PK with FK Reference? [message #757354 is a reply to message #757174] Thu, 17 November 2011 21:30 Go to previous message
Shelli Orton is currently offline Shelli Orton
Messages: 76
Registered: September 2009
Member
Through much trial and error, here is the correct setup:
@Entity
public class Child
{
    private ChildPK childId;
    private String string1;

    public Child()
    {
        // empty constructor
    }

    @EmbeddedId
    public ChildPK getChildId()
    {
        return childId;
    }

    public void setChildId(ChildPK childId)
    {
        this.childId= childId;
    }


    @Column(name = "STRING1")
    public String getString1()
    {
        return string1;
    }

    public void setString1(String string1)
    {
        this.string1 = string1;
    }
    
    // bi-directional many-to-one association to Parent
    @ManyToOne
    @JoinColumn(name = "PARENT_NAME", updatable=false, insertable=false)
    public Parent getParent()
    {
        return this.parent;
    }

    public void setParent(Parent parent)
    {
        this.parent = parent;
    }

}

@Embeddable
public class ChildPK implements Serializable
{
    private static final long serialVersionUID = 1L;
    private String name;
    private String parentName;

    public ChildPK()
    {
        //empty
    }
    

    @Column(name = "NAME")
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name= name;
    }

    @Column(name = "PARENT_NAME")
    public String getParentName()
    {
        return parentName;
    }

    public void setParentName(String parentName)
    {
        this.parentName= parentName;
    }
}
Previous Topic:JPA query - NOT MEMBER OF exception
Next Topic:Re: Mapping Compound PK with FK Reference?
Goto Forum:
  


Current Time: Mon Sep 15 09:28:10 GMT 2014

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

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