问题
I have an entity (representing a music file) that I store in Hibernate. The user can modify attributes of the entity and at some point the changes they make can be saved back to the original file. But at any point in time before they save the changes to the file I would like to able to see differences between the entity that I originally loaded and any changes made since, I want these differences to be stored in the database not the class representing entity because the main reason Im using Hibernate is to mimimize my memory usage. My memory usage could be high otherwise as there can be 1000s of entities in the application.
So it seems the simplest solution is to store the entity twice, with one being a read only copy that I just refer to compare differences, but what is the right way to do this ?
EDIT:So I suggested a solution below that works for me in that when I come to saving changes I can see what has changed, but I now want to take it a step further in two ways. When I load the file next time I start the program I want to check if the file is already in the database with the same/later modification date so I use the record in the database rather than having to parse the file again so my idea was to put the contents of edited into original. But also I would like to give the user to rollback changes in which case I need to keep original.
So now thinking the answer given below about adding dates and and a boolean field rto Song entity might make more sense allowing a user to rollback to any version they like, so I would still keep the SongParent and then have a @oneToMany relationship to song
Alternatively Ive just found the http://www.jboss.org/envers project this may be what i need
回答1:
So I decided to embrace Hibernate and create a superclass that contains two instances of the Song class and this is working for me.
@Entity
public class SongParent
{
@Id
@GeneratedValue
private Integer recNo;
@OneToOne(cascade={CascadeType.ALL})
private Song originalSong;
@OneToOne(cascade={CascadeType.ALL})
private Song editedSong;
public Integer getRecNo()
{
return recNo;
}
public void setRecNo(Integer recNo)
{
this.recNo = recNo;
}
public Song getOriginalSong()
{
return originalSong;
}
public void setOriginalSong(Song originalSong)
{
this.originalSong = originalSong;
}
public Song getEditedSong()
{
return editedSong;
}
public void setEditedSong(Song editedSong)
{
this.editedSong = editedSong;
}
}
回答2:
You can track all changes (I assume they are performed through setters) in ArrayList (pattern Command). Not sure I understood you question correctly.
回答3:
I'am just programming something like this, i can advise you to use a historizing table structure where every table has columns valid_from valid_to (Timestamps) and current (Boolean) only one music file is the current one, and you can see all changes made by using the date-fields!
I also used the command pattern in my application, as mentioned already, to apply changes to the database.
来源:https://stackoverflow.com/questions/8431299/how-do-i-store-a-copy-of-each-entity-i-add-to-database-in-hibernate