-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Tables change dynamically during runtime for custom fields
PostPosted: Fri Mar 20, 2009 3:44 pm 
Newbie

Joined: Fri Jan 23, 2009 4:02 pm
Posts: 6
We are migrating a legacy application to Hibernate that can dynamically alter tables at runtime to handle custom fields. Can anyone suggest how to extend Hibernate to support persisting these fields? Do we need to extend Hibernate classes (and is there a way to register these extensions?) or would custom EventListeners work somehow?

For example, the CustomPerson table looks like this when no custom fields are defined:

Code:
ID int
LastUpdateTime timestamp
PersonId int (foreign key to Person table)


At runtime, additional columns might be added to store the custom fields

Code:
cf1 varchar
cf2 boolean
etc.


The (simplified) entity class looks like:

Code:
@Entity
@Table(name = "customperson")
public class CustomPerson
{
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer recNum;

    @Version @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdateTime;

    @OneToOne @JoinColumn(name = "PersonId", unique = true)
    private Person person;

    @???
    private Map<String, Object> customFieldValues;
}


where the customFieldValues map will hold column names and there values for cf1, cf2, etc.

In addition, we need to support multiple databases with different custom tables via a single SessionFactory, so modifying the Configuration with new mappings at runtime (a la Support of Custom Fields with Hibernate) will not work.

Thanks in advance!
Noah

Hibernate version:
3.3.1

Name and version of the database you are using:
MySQL 5.0, SQL Server 2005
Code:


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 20, 2009 4:51 pm 
Senior
Senior

Joined: Tue Aug 01, 2006 9:24 pm
Posts: 120
What does your database structure look like?

_________________
Please rate my replies as I need points for all of my questions also.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 20, 2009 5:00 pm 
Newbie

Joined: Fri Jan 23, 2009 4:02 pm
Posts: 6
ethnarch wrote:
What does your database structure look like?


The table in question look like this before any custom fields have been added:

Code:
customperson
+----------------+------------------+------+-----+-------------------+----------------+
| Field          | Type             | Null | Key | Default           | Extra          |
+----------------+------------------+------+-----+-------------------+----------------+
| Id             | int(10) unsigned | NO   | PRI | NULL              | auto_increment |
| LastUpdateTime | timestamp        | NO   |     | CURRENT_TIMESTAMP |                |
| PersonId       | int(10) unsigned | NO   | UNI | 0                 |                |
+----------------+------------------+------+-----+-------------------+----------------+


And like this after a couple fields have been defined:
Code:
customperson
+----------------+------------------+------+-----+-------------------+----------------+
| Field          | Type             | Null | Key | Default           | Extra          |
+----------------+------------------+------+-----+-------------------+----------------+
| Id             | int(10) unsigned | NO   | PRI | NULL              | auto_increment |
| LastUpdateTime | timestamp        | NO   |     | CURRENT_TIMESTAMP |                |
| PersonId       | int(10) unsigned | NO   | UNI | 0                 |                |
| cf1            | varchar(255)     | NO   |     |                   |                |
| cf2            | time             | NO   |     |                   |                |
+----------------+------------------+------+-----+-------------------+----------------+


Is that what you meant? Its the dynamic cf* columns that I need to dynamically map to a HashMap<columnName, columnValue>.

Thanks,
Noah


Last edited by noahmiller on Fri Mar 20, 2009 5:55 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 20, 2009 5:20 pm 
Senior
Senior

Joined: Tue Aug 01, 2006 9:24 pm
Posts: 120
I actually use a similar type of mapping. It's easier if you stop looking at the custom fields as part of your first table because it's really not.

Just create 2 classes one for your Person Table and one for your Person Custom Field Tables. And you would use a one to many join.

@Entity
@Table(name = "customperson")
public class CustomPerson
{
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer recNum;

@Version @Temporal(TemporalType.TIMESTAMP)
private Date lastUpdateTime;

@OneToOne @JoinColumn(name = "PersonId", unique = true)
private Person person;

@OneToMany(mappedBy="personId", fetch=FetchType.EAGER, targetEntity=PersonCustomFields.class)
private Set<PersonCustomField> People = new HashSet<PersonCustomField>();
}


I think that's what your looking for. You can use a map also, I just copied and pasted but the map would be a similar but you would use the @MapKey(name="personId") annotation.



@OneToMany(mappedBy="personId", fetch=FetchType.EAGER, targetEntity=PersonCustomFields.class)
@MapKey(name="personId")
private Map<Integer,PersonCustomField> People = new HashMap<Integer,PersonCustomField>();

_________________
Please rate my replies as I need points for all of my questions also.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 20, 2009 5:53 pm 
Newbie

Joined: Fri Jan 23, 2009 4:02 pm
Posts: 6
ethnarch wrote:
I actually use a similar type of mapping. It's easier if you stop looking at the custom fields as part of your first table because it's really not.

Just create 2 classes one for your Person Table and one for your Person Custom Field Tables. And you would use a one to many join.


Sorry, I think I wasn't clear about my table structure. The problem isn't joining the customperson table with the person table with a one-to-one relationship, but rather simply loading the data from the customperson table into the CustomPerson entity.

The problem I have with creating a Hibernate mapping for the "customperson" table is that I don't know at design-time what columns it will have. At runtime, any number of columns may get added to the table (through ALTER TABLE statements). It's these columns that I want to store in a HashMap that holds column names and column values, but Hibernate cannot by default handle that situation.

Any other ideas about how to load and save a dynamic (i.e. unmapped) set of columns?

Thanks,
Noah


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 20, 2009 6:27 pm 
Senior
Senior

Joined: Tue Aug 01, 2006 9:24 pm
Posts: 120
You could use the same types of mappings I described above but in your Person Class just add the getters and setters to access or find the value in the one to many list/map/set(whatever you decide on)

Then mark those getters and setters as @Transient

For instance

@Transient
public String getCustomField01(){
//put code to get customField01 from the PersonCustomFields collection here
}

_________________
Please rate my replies as I need points for all of my questions also.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.