Hi,
I'm using Hibernate 3.2.5 and Hibernate Annotations 3.3.0. I have a problem with a class hierarchy defined with annotations using InheritanceType.JOINED . I have a bunch of common attributes in the parent abstract class (in T_RESOURCE table), and specific attributes in subclass tables (T_SQLQUERY_RESOURCE and T_FILE_RESOURCE for example).
Code:
@Entity(name="T_RESOURCE")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractLogLinesResource implements Cloneable {
private static final Logger log=Logger.getLogger(AbstractLogLinesResource.class);
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="RESOURCE_ID")
private long id;
@ManyToOne
@JoinColumn(name = "RESOURCE_RELATED_APPLICATION_ID")
@ForeignKey(name = "FK_RESOURCE_APPLICATION")
private Application relatedApplication;
@OneToMany(mappedBy="relatedResource")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<IndicatorFromFile> indicatorsToGet=new TreeSet<IndicatorFromFile>();
@OneToMany(mappedBy="relatedResource")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<PatternToExclude> patternsToExclude=new TreeSet<PatternToExclude>();
...
}
@Entity(name="T_FILE_RESOURCE")
public class FileLogLinesResource extends AbstractLogLinesResource {
public final static int SORT_FILE_BY_NAME=1;
public final static int SORT_FILE_BY_MODIFIED_DATE=2;
private static Logger log=Logger.getLogger(FileLogLinesResource.class);
@Column(name="FILERESOURCE_PATH")
private String path;
...
}
@Entity(name="T_SQLQUERY_RESOURCE")
public class SQLqueryLogLinesResource extends AbstractLogLinesResource {
private static Logger log=Logger.getLogger(SQLqueryLogLinesResource.class);
@Column(name="SQLQUERY_RESOURCE_URL")
private String connectionUrl;
@Column(name="SQLQUERY_RESOURCE_LOGIN")
private String login;
@Column(name="SQLQUERY_RESOURCE_PASSWORD")
private String password;
...
}
I can persist the sublasses with no problem, it will create a row in both T_RESOURCE AND SQLQUERY_RESOURCE tables (for example). What I'm struggling with though, is in case I want to update a SqlQueryResource into a FileResource. For some reason, all the other common attributes will be the same, but what is one day in a database can be the day after in a file, and I need to be able to reflect that change.
I'm using a getCopy method which generates the new class and copies common attributes. However, I can't find a way to save this object without getting different exceptions, from
Code:
StaleStateException: Batch update returned unexpected row count from update [0].
when deleting and re-creating a copy of a different type, to
Code:
StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
when trying to save an updated object with the same ID.
What is the strategy in that case ? Basically, when saving my object with its new implementing class, I want hibernate to delete on one side (T_SQLQUERY_RESOURCE), insert on the other (T_FILE_RESOURCE) with the same ID, and don't do anything in the common table (T_RESOURCE). This way, I would be able to easily keep all the links I have at the parent class level.
Thanks in advance, a solution to that problem would make my day !
--
Vincent