views:

316

answers:

4

Hello,

So i am stuck, i am creating a gwt web application, i will be using a tree(gwt Tree and TreeItems) structure to show a list of folders(class Folder) and files(class FileLocation), the folder and filelocation class will all implement a Hierarchy interface basing the classes on the composite pattern. but i am using hibernate to store my data , and i am using annotations for the mapping of the data to the database. my trouble is i do not know how to annotate my interface.

have any of you guys used the composite pattern while persisting the data with hibernate

public interface Hierarchy(){
// a few abstract methods that will be implemented by the sub classes
 }


@Entity
@Table()
public class Folder implements Serializable, Hierarchy {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "folder_id", updatable = false, nullable = false)
private int id;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "FOLDER_FILELOCATION", joinColumns = { 
        @JoinColumn(name = "folder_id") }, inverseJoinColumns = { 
        @JoinColumn(name = "file_information_id") })
private List<Hierarchy> children = new ArrayList<Hierarchy>() ;
@Column(name = "folder_name")
private String folderName;
@Column(name = "tree_item")
private TreeItem item;
@Column (name = "parent")
private Hierarchy parent;



@Entity
@Table(name = "FILE_INFORMATION_TABLE")
public class FileInformation implements Serializable, Hierarchy {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "file_information_id", updatable = false, nullable = false)
private int fiId;
@Column (name = "location")
private String location;
@Column(name = "tree_item")
private TreeItem item;
@Column (name = "parent")
    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinTable(name="FOLDER_FILELOCATION",
    joinColumns = @JoinColumn(name="filelocation_id"),
    inverseJoinColumns = @JoinColumn(name="folder_ID"))  
private Hierarchy parent;
A: 

Composite is very basic hibernate mapping and shouldn't be a problem.
But i don't understand the Mapping. I assume FOLDER_FILELOCATION is a LinkTable between Folder and FileInformation. If so you actually do not have a OneToMany but a ManyToMany Relation. But you can map it as a OneToMany though.
What exaclty is the problem you are facing? To get more precise answers please spend some more time explaining your concrete problem. Formatting the given code also helps but ok, i'll give it a try.

I am not exactly sure but i think based on the model i assume you have you should try this:

public interface Hierarchy(){
// a few abstract methods that will be implemented by the sub classes
}


@Entity
@Table(name = "FOLDER_TABLE")
public class Folder  implements Hierarchy, Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "folder_id", updatable = false, nullable = false)
    private int id;

    @OneToMany
    @JoinTable(
            name="FOLDER_FILELOCATION",
            joinColumns = @JoinColumn( name="folder_id"),
            inverseJoinColumns = @JoinColumn( name="filelocation_id")
    )   
    private List<Hierarchy> children = new ArrayList<Hierarchy>() ;

    @Column(name = "folder_name")
    private String folderName;

    @Column(name = "tree_item")
    private TreeItem item;

    @Column (name = "parent")
    private Hierarchy parent;
}

@Entity
@Table(name = "FILE_INFORMATION_TABLE")
public class FileInformation implements Hierarchy, Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "file_information_id", updatable = false, nullable = false)
    private int fiId;

    @Column (name = "location")
    private String location;
    @Column(name = "tree_item")
    private TreeItem item;

    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinTable(name="FOLDER_FILELOCATION",
        joinColumns = @JoinColumn(name="filelocation_id"),
        inverseJoinColumns = @JoinColumn(name="folder_ID")
    )   
    private Hierarchy parent;
}

Hopefully this helps.

zoidbeck
Initial SessionFactory creation failed.org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.example.client.FileInformation.parent references an unknown entity: com.example.client.HierarchyI get this error with your implementation same one as i was getting.I must have to annotate the interface but i dont know what to doAlso i changed FOLDER_FILELOCATION to FOLDER_JOIN_FILELOCATION!
molleman
A: 

I'm not 100% sure of what you're trying to do (you're extending an interface, the parent is missing a @ManyToOne annotation) but, to my knowledge, interface are not supported by annotations (they are not part of the JPA spec). See HHH-4413 and also this discussion. You may need to use XML mappings instead for this.

Pascal Thivent
sorry i was testing with Hierarchy as an abstract class and copied and pasted the code. i fixed it up
molleman
A: 

After a look through the hibernate documentation and This Book i was able to find a solution to my problem. i cannot use an interface for the moment with JPA annotations. so i used an abstract class with mappings that supported inheritance. in this example i use a single table to store all the values. but i wil look in to seperating them.

@Entity
@Table(name ="HIERARCHY")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(
    name = "HIERARCHY_TYPE", discriminatorType = DiscriminatorType.STRING)      
public abstract class  Hierarchy implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "hierarchy_id", updatable = false, nullable = false)
private int hId;



@Entity
@DiscriminatorValue("F")
public class Folder extends Hierarchy  {

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "FOLDER_JOIN_FILELOCATION", joinColumns = { 
        @JoinColumn(name = "folder_id") }, inverseJoinColumns = { 
        @JoinColumn(name = "file_information_id") })
private List<Hierarchy> children = new ArrayList<Hierarchy>() ;
@Column(name = "folder_name")
private String folderName;
//@Column(name = "tree_item")
//private TreeItem item;
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
   @JoinTable(name="FOLDER_JOIN_FOLDER",
        joinColumns = @JoinColumn(name="parent_folder_id"),
        inverseJoinColumns = @JoinColumn(name="folder_ID")
    ) 
private Hierarchy parent;




@Entity
@DiscriminatorValue("FI")
public class FileInformation extends Hierarchy  {


@Column (name = "location")
private String location;
//@Column(name = "tree_item")
//private TreeItem item;
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
   @JoinTable(name="FILEINFORMATION_JOIN_FOLDER",
        joinColumns = @JoinColumn(name="filelocation_id"),
        inverseJoinColumns = @JoinColumn(name="folder_ID")
    )  
private Hierarchy parent;
molleman
A: 

Thanks. This is a useful post. Could you post your full solution and the sql statements to create tables etc.

Farshid
The annotations create the SQL statements for you and so the SQL statements are hidden in the background. Depending hibernate config file tables may be recreated or updated.@Table will relate the specified object to that table with the name supplied. Table joins can be added if and more than likley when needed. I won't be posting the full solution online. If you need any help while try to create the composite pattern with your project , I will then help you. Create your own thread.!
molleman