Hello.
I have tried a little refactoring of my Java code but am having trouble getting it right. I had two superclasses with two subclasses each and the subclasses had a corresponding connection to the other, like this
Code:
AppRoleType ---- * AppRole
| |
| SubRoleType2 --* SubRole2 |
| | | |
RoleType Role ---
* *
| |
App Person
So I had Role and RoleType as concrete classes and that worked but I think they should be abstract and would like to use them with polymorphism, call getRoleType() on any Role but I only want to have the correct corresponding type.
Previously I had getAppRoleType and so on but I'd like to be able to just call getRoleType.
When it comes to the code I have
Code:
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class RoleType {
// protected Set<Role> roles_; //removed from base class
public void setApp(App app) {
app_ = app;
}
@XmlElement
@ManyToOne
@JoinColumn(name = "APP_ID")
public App getApp() {
return app_;
}
/*REMOVED from base class, can't use polymorphism and then control what
* type in subclass (i.e. only accept AppRole in AppRoleType)
* Not good design to leave out though...?
public void setRoles(Set<Role> roles) {
roles_ = roles;
}*/
public abstract Set<? extends Role> getRoles();
}
@Entity
public class AppRoleType extends RoleType {
private Set<AppRole> appRoles_;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "roleType")
public Set<AppRole> getRoles() {
return appRoles_;
}
public void setRoles(Set<AppRole> appRoles) {
appRoles_ = appRoles;
}
public void addAppRole(AppRole appRole) {
if(getRoles() == null) {
appRoles_ = new HashSet<AppRole>();
}
appRoles_.add(appRole);
}
}
And similar code on Role but with ManyToOne mapping.
Code:
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Role {
// protected RoleType roleType_;
/*REMOVED from base class, can't use polymorphism and then control what
* type in subclass (i.e. only accept AppRoleType in AppRole)
* Not good design to leave out though...?
public void setRoleType(RoleType roleType) {
roleType_ = roleType;
}*/
// @XmlElement
// @ManyToOne(fetch = FetchType.EAGER)
// @JoinColumn(name = "RTYP_ID")
public abstract RoleType getRoleType(); //{
// return roleType_;
// }
}
@Entity
public class AppRole extends Role {
private AppRoleType appRoleType_;
@ManyToOne
@JoinColumn(name = "APPRT")
public AppRoleType getRoleType() {
return appRoleType_;
}
public void setAppRoleType(AppRoleType appRoleType) {
appRoleType_ = appRoleType;
}
}
Well I guess I'm having trouble with the App class since it is now referencing an abstract class and you cannot have an association pointing to a mapped superclass, it has to be an entity.
"Use of @OneToMany or @ManyToMany targeting an unmapped class"
So that means that trying to make it abstract in this case is doomed. What would be the best solution for something like this (to be able to call getRoleType() on any Role etc. and not getting AppRoleType in SubRole2)?
I am not a hundred percent sure on the generics in the code to control that but I guess this is for Hibernate questions... :)