You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Heather Sterling <hs...@us.ibm.com> on 2009/02/04 15:38:23 UTC
many-to-many self-referencing
Hi,
I am trying to map our current schema to JPA. The below SoftwareModule
entity has many-to-many mappings with other entities and those are working
correctly. However, I cannot get it to work for a self-referencing
many-to-many mapping.
JPA is not throwing any exceptions when I try to do the following. It just
seems to completely ignore the fact that I set the targetModules. Most of
the info I was able to dig up online showed the exact same strategy I am
already using.
1) Persist SoftwareModuleA
2) Set the target modules for SoftwareModuleB to be SoftwareModuleA and
persist SoftwareModuleB.
3) Query for SoftwareModules :
"select x from SoftwareModule x where x.targetModules is not null" -->
returns 0 results
"select x from SoftwareModule x where x.targetModules is null" --> returns
both of the SoftwareModule's
4) The only other interesting thing of note is that this class inherits
from a base class, but I'm not sure that is playing any part in this
problem.
@Entity(name="SoftwareModule")
@Table(name="SOFTWARE_MODULE")
@PrimaryKeyJoinColumn(name="MODULE_ID", referencedColumnName="id")
public class JPASoftwareModule extends JPAManagedElement implements
Serializable {
...........
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="sftw_mod_sftw_mod_assoc",
joinColumns=@JoinColumn(name="source_module_id"),//
referencedColumnName="module_id"),
inverseJoinColumns=@JoinColumn(name="target_module_id"))//,
referencedColumnName="module_id"))
private List<JPASoftwareModule> sourceModules;
@ManyToMany(fetch=FetchType.EAGER, mappedBy="sourceModules")
private List<JPASoftwareModule> targetModules;
Thanks
Heather Sterling
Systems Management Development
Phone: 919-254-7163 T/L: 444-7163
Cell: 919-423-3143
Email: hsterl@us.ibm.com
Re: many-to-many self-referencing
Posted by "B.J. Reed" <bj...@gmail.com>.
Hi Heather, Not seeing your calling code, I can't tell exactly what's
wrong. I tried to stay as close to your algorithm as I could and I did
get this to work with the following: I'm not inheriting from another
class and I commented out the PrimaryKeyJoinColumn and used my own int
id. I believe the rest of your class is unchanged.
@Entity(name="SoftwareModule")
@Table(name="SOFTWARE_MODULE")
//@PrimaryKeyJoinColumn(name="MODULE_ID", referencedColumnName="id")
public class JPASoftwareModule implements Serializable {
@Id
private int id;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="sftw_mod_sftw_mod_assoc",
joinColumns=@JoinColumn(name="source_module_id"),//referencedColumnName="module_id"),
inverseJoinColumns=@JoinColumn(name="target_module_id"))//,referencedColumnName="module_id"))
private List<JPASoftwareModule> sourceModules;
@ManyToMany(fetch=FetchType.EAGER, mappedBy="sourceModules")
private List<JPASoftwareModule> targetModules;
public JPASoftwareModule () {
sourceModules = new ArrayList<JPASoftwareModule>();
targetModules = new ArrayList<JPASoftwareModule>();
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public List<JPASoftwareModule> getSourceModules() {
return sourceModules;
}
public List<JPASoftwareModule> getTargetModules() {
return targetModules;
}
public String toString () {
String buffer = "SOFTWARE MODULE";
buffer += "\nid=" + id;
buffer += "\nsources";
for (int i = 0; i < sourceModules.size(); i++)
buffer += "\n id=" + sourceModules.get(i).getId();
buffer += "\ntargets";
for (int i = 0; i < targetModules.size(); i++)
buffer += "\n id=" + targetModules.get(i).getId();
return buffer;
}
my calling code:
EntityManager em = emf.createEntityManager();
// Create some entities
JPASoftwareModule source1 = new JPASoftwareModule();
source1.setId(1);
em.getTransaction().begin();
em.persist(source1);
em.getTransaction().commit();
JPASoftwareModule target2 = new JPASoftwareModule();
target2.setId(2);
JPASoftwareModule target3 = new JPASoftwareModule();
target3.setId(3);
source1.getSourceModules().add(target2);
source1.getSourceModules().add(target3);
target2.getTargetModules().add(source1);
target3.getTargetModules().add(source1);
em.getTransaction().begin();
em.persist(target2);
em.persist(target3);
em.getTransaction().commit();
try{
Query q = em.createQuery("select e from SoftwareModule e
where e.targetModules is not null");
List<JPASoftwareModule> elist = q.getResultList();
System.out.println("TARGET MODULES IS NOT NULL");
for (JPASoftwareModule e : elist) {
System.out.println(e.toString());
}
q = em.createQuery("select e from SoftwareModule e where
e.targetModules is null");
elist = q.getResultList();
System.out.println("TARGET MODULES IS NULL");
for (JPASoftwareModule e : elist) {
System.out.println(e.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
I got the following output
TARGET MODULES IS NOT NULL
SOFTWARE MODULE
id=2
sources
targets
id=1
SOFTWARE MODULE
id=3
sources
targets
id=1
TARGET MODULES IS NULL
SOFTWARE MODULE
id=1
sources
id=2
id=3
targets
Let me know if this helps any.
--B.J. Reed.
Heather Sterling wrote:
> Hi,
>
> I am trying to map our current schema to JPA. The below SoftwareModule
> entity has many-to-many mappings with other entities and those are working
> correctly. However, I cannot get it to work for a self-referencing
> many-to-many mapping.
>
> JPA is not throwing any exceptions when I try to do the following. It just
> seems to completely ignore the fact that I set the targetModules. Most of
> the info I was able to dig up online showed the exact same strategy I am
> already using.
>
> 1) Persist SoftwareModuleA
> 2) Set the target modules for SoftwareModuleB to be SoftwareModuleA and
> persist SoftwareModuleB.
> 3) Query for SoftwareModules :
>
> "select x from SoftwareModule x where x.targetModules is not null" -->
> returns 0 results
>
> "select x from SoftwareModule x where x.targetModules is null" --> returns
> both of the SoftwareModule's
>
> 4) The only other interesting thing of note is that this class inherits
> from a base class, but I'm not sure that is playing any part in this
> problem.
>
>
>
> @Entity(name="SoftwareModule")
> @Table(name="SOFTWARE_MODULE")
> @PrimaryKeyJoinColumn(name="MODULE_ID", referencedColumnName="id")
> public class JPASoftwareModule extends JPAManagedElement implements
> Serializable {
>
> ...........
>
> @ManyToMany(fetch=FetchType.EAGER)
> @JoinTable(name="sftw_mod_sftw_mod_assoc",
> joinColumns=@JoinColumn(name="source_module_id"),//
> referencedColumnName="module_id"),
> inverseJoinColumns=@JoinColumn(name="target_module_id"))//,
> referencedColumnName="module_id"))
> private List<JPASoftwareModule> sourceModules;
>
> @ManyToMany(fetch=FetchType.EAGER, mappedBy="sourceModules")
> private List<JPASoftwareModule> targetModules;
>
>
> Thanks
>
> Heather Sterling
> Systems Management Development
> Phone: 919-254-7163 T/L: 444-7163
> Cell: 919-423-3143
> Email: hsterl@us.ibm.com
>