2 Replies Latest reply on Jul 18, 2006 5:28 AM by gnulp

    Complex Id and Joined Inheritance

    dabubble

      Hi!

      I hava two classes that have the following structure:

      @Entity
      @SequenceGenerator(name = "crawlerdocument_sequence", sequenceName = "crawlerdocument_id_seq")
      @Inheritance(strategy = InheritanceType.JOINED)
      public abstract class CrawlerDocument implements Serializable {
      
       //The states a document can have in the DB
       /**
       * This state transcribes the normal state of a document
       */
       public static final int IDLE = 0;
       /**
       * This state transcribes that the document is being crawled/indexed
       */
       public static final int UPDATING_REPOSITORY = 1;
       /**
       * This state transcribes the document has been updated in the filesystem
       */
       public static final int UPDATED = 2;
       /**
       * This state transcribes the document has not been changed in the file system
       */
       public static final int NOT_CHANGED = 3;
       /**
       * This state transcribes the document has been created int he file system
       */
       public static final int INSERTED = 4;
      
       protected Permissions permissions;
      
       protected Repository repository;
      
       private int state;
      
       private Long id;
      
       public CrawlerDocument(){}
      
       @Id
       @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "crawlerdocument_sequence")
       public Long getId() {
       return id;
       }
      
       @Column(length = 2700)
       public Permissions getPermissions(){
       return this.permissions;
       }
      
       public void setPermissions(Permissions permissions){
       this.permissions = permissions;
       }
      
      
       @ManyToOne(targetEntity = Repository.class , optional=false,fetch = FetchType.EAGER)
       public Repository getRepository(){
       return this.repository;
       }
      
       public void setRepository(Repository repository){
       this.repository = repository;
       }
      
       public void setState(int state){
       this.state = state;
       }
      
       public int getState(){
       return this.state;
       }
      
       public void setId(Long id) {
       this.id = id;
       }
      }
      


      A another class that extends this class:

      @Entity
      @IdClass(FileSystemCrawlerDocumentPK.class)
      public class FileSystemCrawlerDocument extends CrawlerDocument{
      
       private static final long serialVersionUID = 4457330551129440853L;
      
       private String fullPath;
       private String rootPath;
       private String fileName;
       private String repositoryRelativePath;
       private Date lastChanged;
      
       public FileSystemCrawlerDocument(){}
      
       /**
       * Contructor to be used only for directories, though they are not saved we can process
       * the path in order to keep the part after the root path
       * @param fullPath
       * @param rootPath
       */
       public FileSystemCrawlerDocument(String fullPath,String rootPath){
       this.fullPath = fullPath;
       this.rootPath = rootPath;
       this.repositoryRelativePath = fullPath.substring(rootPath.length());
       this.permissions = new Permissions();
       }
      
       /**
       * Contructor to be used for the processed files these inherit both the permissions
       * and the relative path of the parent directory
       * @param parent
       * @param fileName
       */
       public FileSystemCrawlerDocument(FileSystemCrawlerDocument parent, String fileName){
       this.fileName = fileName;
       this.repositoryRelativePath = parent.getRepositoryRelativePath();
       this.permissions = parent.getPermissions();
       }
      
       @Transient
       public String getFullPath() {
       return fullPath;
       }
      
       public void setFullPath(String fullPath) {
       this.fullPath = fullPath;
       }
      
       @Transient
       public String getRootPath() {
       return rootPath;
       }
      
       public void setRootPath(String rootPath) {
       this.rootPath = rootPath;
       }
      
       @Id
       @Column(length = 1500)
       public String getFileName() {
       return fileName;
       }
      
       public void setFileName(String fileName) {
       this.fileName = fileName;
       }
      
       @Id
       @Column(length = 2700)
       public String getRepositoryRelativePath() {
       return repositoryRelativePath;
       }
      
       public void setRepositoryRelativePath(String repositoryRelativePath) {
       this.repositoryRelativePath = repositoryRelativePath;
       }
      
      
       public String toString() {
       return "FileSystemCrawlerDocument{" +
       "fullPath='" + fullPath + '\'' +
       ", rootPath='" + rootPath + '\'' +
       ", fileName='" + fileName + '\'' +
       ", repositoryRelativePath='" + repositoryRelativePath + '\'' +
       ", repository=" + repository +
       ", permissions=" + permissions +
       '}';
       }
      
       @Temporal(TemporalType.TIMESTAMP)
       public Date getLastChanged() {
       return lastChanged;
       }
      
       public void setLastChanged(Date lastChanged) {
       this.lastChanged = lastChanged;
       }
      }
      



      This second class uses the following id class:

      public class FileSystemCrawlerDocumentPK implements Serializable {
      
       private String fileName;
       private String repositoryRelativePath;
      
       public String getFileName() {
       return fileName;
       }
      
       public void setFileName(String fileName) {
       this.fileName = fileName;
       }
      
       public String getRepositoryRelativePath() {
       return repositoryRelativePath;
       }
      
       public void setRepositoryRelativePath(String repositoryRelativePath) {
       this.repositoryRelativePath = repositoryRelativePath;
       }
      
       public boolean equals(Object o) {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
      
       final FileSystemCrawlerDocumentPK that = (FileSystemCrawlerDocumentPK) o;
      
       if (!fileName.equals(that.fileName)) return false;
       if (!repositoryRelativePath.equals(that.repositoryRelativePath)) return false;
      
       return true;
       }
      
       public int hashCode() {
       int result;
       result = fileName.hashCode();
       result = 29 * result + repositoryRelativePath.hashCode();
       return result;
       }
      }
      


      The objective is to map to a DB model a bit like this

      Table CrawlerDocument
      id, int , sequence, pk
      attr 1
      attr 2

      Table FileSystemCrawlerDocument
      id (from CrawlerDocument), int , sequence, pk, fk
      fileName, pk
      relativeRootPath, pk
      attr3
      attr4



      I can't seem to get this to work.

      I gives me the following error:

      org.hibernate.AnnotationException: Unable to define/override @Id(s) on a subclass: com.criticalsoftware.search.entities.FileSystemCrawlerDocument


      I'm using Jboss 4.0.4 GA with EJB3


      Any help would be very much appreciated.

        • 1. Re: Complex Id and Joined Inheritance
          gnulp

          any feedback on that issue ? I have the same exception ...

          it seems not to be possible to derive from a class as well as having a relation on the same class ...

          • 2. Re: Complex Id and Joined Inheritance
            gnulp

            found the problem ...

            deriving with the primary key set twice does not work - which is in principle ok ...

            in the given example the primary keys of the derived class should be changed to a unique key constraint - and it will get the same primary key as the top class

            ==> this should work ...