JPA ManyToMany Not Populating Object Property
In JPA, I am trying to create an Update screen for an JPA object with a list of categories for that object. This is a many to many relationship.
I am creating a join relationship on the table within the JPA object that has the following properties.
Classes.java
@JoinTable(name = "classes_has_class_categories",joinColumns = {
@JoinColumn(name = "classes_id", referencedColumnName = "id")}, inverseJoinColumns = {
@JoinColumn(name = "class_categories_id", referencedColumnName = "id")})
@ManyToMany(cascade = CascadeType.ALL)
private Collection<ClassCategories> classCategoriesCollection;
The key to my question is contained within the below logic as I have updated the database and everything is great within the DB. However, my problem is that when I access the object at a later time, the classCategoriesCollection property within the object doesn't have all of the correct objects. I would have thought that my flush and refresh calls below would have synchronized everything up with the database开发者_高级运维, but that object property is still empty UNTIL I redeploy/recompile the application. Please help me with knowing how to get this object to sync up with the current database in the object.
ClassManager.java
for(String c : cats)
{
int cId = ConvertToInt(c);
ClassCategories ca = em.find(ClassCategories.class, cId);
if(ca != null)
{
try{
if(!cla.getClassCategoriesCollection().contains(ca))
{
ClassHasCategoriesPK classHasCategoriesPK= new ClassHasCategoriesPK();
classHasCategoriesPK.setCategoryId(ca.getId());
classHasCategoriesPK.setClassId(cla.getId());
ClassHasCategories cd = new ClassHasCategories(classHasCategoriesPK);
em.persist(cd);
em.flush();
}
}
catch (Exception ex)
{}
}
}
em.persist(cla); //cla is the Class object instance.
em.flush();
em.refresh(cla);
Later on in the code....
request.setAttribute("classCategories",cl.getClassCategoriesCollection());
Doesn't have the right classes until a recompile of the application.
Why do you have a ClassHasCategories
class for a M_N relationship table when your relationship has no extra parameters? Since Classes
has a @ManyToMany(cascade = CascadeType.ALL)
relationship with ClassCategories
, all you need to be doing is something like:
classObj.getClassCategoriesCollection().add(classCategoryObj);
em.merge(classObj).
The provider will take care of updating the relationship table. You can also remove items from classCategoriesCollection
using similar logic:
classObj.getClassCategoriesCollection().remove(classCategoryObj);
em.merge(classObj).
So, the answer is:
- If
classes_has_class_categories
has no columns but the pk with two fks, get ride ofClassHasCategories
andClassHasCategoriesPK
. Work withclassCategoriesCollection
to update the relationship table. - If
classes_has_class_categories
has extra columns, then redo your mapping in a way thatClassHasCategoriesPK
has two@ManyToOne
relationships, respectively forClasses
andClassCategories
. Update relationships by directly manipulatingClassHasCategories
. Here is a code example.
The rule of thumb is, never mix both strategies (like you are doing by having both a @ManyToMany
relationship and a separate ClassHasCategories
object for the same table).
Cheers,
精彩评论