Hello everyone. I've been getting lost for the better part of the last two days on the following issue.
First of all I'll mention the database tables:
Code:
MONITOR
---------
ID (PK),
NAME,
USER,
HOST,
etc...
(name + user + host = unique)
Code:
FILESYSTEM
------------
ID (PK),
MOUNT_POINT
etc...
MONITORED_BY (FK on MONITOR.ID)
PING
------------
ID,
TARGET_IP
etc...
MONITORED_BY (FK on MONITOR.ID)
Now, one problem I faced was that in the java entity that mapped the MONITOR table I didn't want to have two instance variables that looked like this:
Code:
private Set<FilesystemEntity>, Set<PingEntity>
because I know that I'll never require both Sets at the same time, and I wanted he Monitor class to be independent of the actually monitored resources (say that in the future I make a third table, called TABLESPACES, I don't want to recompile the Monitor class).
Here is what I did:
1) a jar called core.jar, in which I placed this:
Code:
@MappedSuperclass
@NamedQueries({
@NamedQuery(name = "findMonitor", query = "from JmonMonitor mon where mon.shell = :shell and mon.host = :host and mon.username = :username and mon.active = 0")})
public abstract class AbstractMonitor implements Serializable {
private long id;
private String name;
private String host;
private String user;
...
This jar has no persistence.xml in it.
2) a jar called filesystem.jar, in which I placed this:
Code:
@Entity
@Table(name="MONITOR", uniqueConstraints = @UniqueConstraint(columnNames={"NAME", "HOST", "USER"}))
public class JmonMonitor extends AbstractMonitor {
private Set<FilesystemEntity> fsEntities = new HashSet<FilesystemEntity>(0);
....
@Entity
@Table(name="FILESYSTEM", uniqueConstraints = @UniqueConstraint(columnNames={"MOUNT_POINT", "MONITORED_BY"}))
public class FilesystemEntity implements Serializable {
....
This jar has those two classes in his persistence.xml.
3) a jar called ping.jar, in which I placed this:
Code:
@Entity
@Table(name="MONITOR", uniqueConstraints = @UniqueConstraint(columnNames={"NAME", "HOST", "USER"}))
public class JmonMonitor extends AbstractMonitor {
private Set<PingEntity> pingEntities = new HashSet<PingEntity>(0);
....
@Entity
@Table(name="PING", uniqueConstraints = @UniqueConstraint(columnNames={"TARGET_IP", "MONITORED_BY"}))
public class PingEntity implements Serializable {
....
This jar has those two classes in his persistence.xml.
Now, those 2 projects work ok when used separately. I imagine that the NamedQuery called like this:
Code:
Query query = entityManager.createNamedQuery("findMonitor");
query.setParameter("name", name);
query.setParameter("host", host);
query.setParameter("user", user);
AbstractMonitor jMonMonitor = (AbstractMonitor)query.getSingleResult();
returns the proper subclass of AbstractMonitor each time because there is just one?
Moving on to what caused my issue, I wanted to add a new table yesterday, which looks like this:
Code:
SCHEDULER
-----------
ID (PK),
MONITOR_ID (FK on MONITOR.ID)
etc...
The java class would look like:
Code:
@Entity
@Table(name="SCHEDULER")
public class Scheduler implements Serializable {
....
private AbstractMonitor monitor;
Now, I've come to understand that since AbstractMonitor isn't an entity, it can't be used like that, which is why I get this exception:
Quote:
"org.hibernate.AnnotationException: @OneToOne or @ManyToOne on example.Scheduler references an unknown entity: example.AbstractMonitor"
The problem is, how do I keep a superclass reference in the Scheduler (because I'm not sure if that entry is scheduling a Filesystem or a Ping monitor)?
Thanks a lot everyone,
Roberto