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",
joincolum...@joincolumn(name="source_module_id"),//referencedColumnName="module_id"),
inversejoincolum...@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",
joincolum...@joincolumn(name="source_module_id"),//
referencedColumnName="module_id"),
inversejoincolum...@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: [email protected]