0

I have a "Folder" class, that has many files, just like below

class Folder {
   ...

   @ManyToMany
   private Set<File> files= new HashSet<>();
}

I need to save not only the files that a folder has, but also the order of that file for that folder (it can be different for others). If I have 3 files: "X Y Z", I also need to know that:

X = 1st
Y = 2nd
Z = 3rd

Now that you understood the problem, there is something more. The files have types.

class File {
   ...

   @ManyToOne
   private FileType type;
}

Each type of file will generate a different ordering on the Folder.

So, I can have a folder with 4 files:

"X", type "jpeg"
"Y", type "jpeg"
"Z", type "png"
"W", type "png"

In this case, it should be

For type jpeg, X = 1st, Y = 2nd
For type png, Z = 1st, W = 2nd

I am not sure what is the best way to do this.

  • Should I create another class that will hold the relation? I would still have a problem to differentiate filetypes.
  • Should I create a Map<FileType, FileWithOrder> so I can separate each filetype and then give them an integer with their order number?
  • Other better sugestion? :)

I hope I was clear enough on my problem. Thanks

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
rtmc
  • 109
  • 1
  • 7
  • 3
    Change `HashSet` by `LinkedHashSet`, or use `List` instead of `Set`. Note that the latter depends on your requirements. – Luiggi Mendoza Nov 07 '13 at 19:17
  • Luiggi has good suggestions. Personally I would List and add an ordernum column to the File table. – David Fleeman Nov 07 '13 at 19:20
  • That would solve all the problems without any hardcode. Thanks very much. I will try. Is there any difference by using Set/List? – rtmc Nov 07 '13 at 19:21
  • Check their javadocs and do some tests. – Luiggi Mendoza Nov 07 '13 at 19:21
  • `implements Comparable` in your `File` and define the sort order as `natural` in Hibernate, Hibernate will then return a `SortedSet`. Note, it's best not to name your classes the same thing as commonly used Java API classes. – Boris the Spider Nov 07 '13 at 19:21
  • 1
    Set will not maintain orderings. List maintains ordering but requires an additional column to store it. – David Fleeman Nov 07 '13 at 19:21
  • @DavidFleeman `LinkedHashSet` do maintain the order the elements were inserted, similar to a `List` but satisfying the contract of a `Set`. – Luiggi Mendoza Nov 07 '13 at 19:22
  • @LuiggiMendoza Hibernate cannot persist a `LinkedHashSet` - it will just return a `HashSet`. – Boris the Spider Nov 07 '13 at 19:22
  • Hmmm, I have not used that one -- does it also require an extra column to hold order? – David Fleeman Nov 07 '13 at 19:22
  • About Set vs List: http://stackoverflow.com/q/1035008/1065197 – Luiggi Mendoza Nov 07 '13 at 19:23
  • @BoristheSpider - that is my understanding in hibernate -- the order will be lost if you use even LinkedHashSet once you persist to db and then read back out. – David Fleeman Nov 07 '13 at 19:24
  • @DavidFleeman Yup. But you can ask for Hibernate to add a `sort` to the database query - in which case it will return a `LinkedHashSet`. You can also ask Hibernate to sort in Java - in which case it will use an ordered collection - i.e. one that `extends SortedSet`. – Boris the Spider Nov 07 '13 at 19:26
  • If we know how to tell Hibernate to "sort" without having an ordernum column, then it does not matter if we store the data in the correct order or not. The retrieval process will simply sort it the way we want it to appear. So there is a missing piece of info to the question -- do they NEED to be stored in sorted order (eg., the order is NOT reproducible based on the data properties), or can they be stored in any order and the order simply applied when retrieving the data by an order by statement? If the latter is true, then Set will work fine. Otherwise, List is necessary. – David Fleeman Nov 07 '13 at 19:30
  • So I think i should add @Sort for files using LinkedHashSet. I will try it. – rtmc Nov 07 '13 at 19:31
  • @DavidFleeman it can be stored in ANY ORDER. I just need to show it later in the right order. – rtmc Nov 07 '13 at 19:32
  • @rtmc - There you go -- Set works fine if the order can be reproduced by the data properties. – David Fleeman Nov 07 '13 at 19:33
  • IMO this is a good example of why not to use `Set` when working with Hibernate thought... – Luiggi Mendoza Nov 07 '13 at 19:34
  • @LuiggiMendoza - If I am building from scratch, I would use List usually. However, when you don't have the authority to dictate the database schema, it's good to know that you can make Set work to maintain order. In your particular use case though, you need to do some performance analysis because if these lists are changing frequently, then there will be a lot more "updating" happening in the DB with the List approach whereas the Set approach would require less DB operations if frequent updates are being made to the lists. Just something to consider. – David Fleeman Nov 07 '13 at 19:43
  • @DavidFleeman but Java classes must not be tightly coupled to database schema, so you can use `List` in this case as well. And IMO you should also customize if the collection field must update the database (always insert/update/delete) or if is just for read (select) operations and any change on the list must not modify the database elements, but this design, again, depend on your needs. – Luiggi Mendoza Nov 07 '13 at 19:47
  • I could not make it with LinkedHashSet. The hibernate just returns a persistent set or something similar and does not maintan the order. I really didn't want to worry about ordering and stuff. I changed to List and worked fine. Because I can reorder elements easily and persist back. Thanks – rtmc Nov 07 '13 at 20:17

1 Answers1

0

If you want to keep track of the insertion order, I think a List is more adapted than a Set. As for the separation by file type, I would create a Map<FileType, List<File>> in addition to the global list.

This is for the Java side, but I don't know how this would be persisted by Hibernate.

Joffrey
  • 32,348
  • 6
  • 68
  • 100
  • It's (almost) impossible to persist a collection of collections in Hibernate. – Boris the Spider Nov 07 '13 at 19:28
  • Yeah that's what I'm afraid of. I guess thinking about it on the database side would be better to start with, then adapt the loaded data to this kind of Java structures. – Joffrey Nov 07 '13 at 19:30