Reputation: 9488
I have two classes which need to be XML mapped (eventually they will all be modified to Annotations, but currently we need to support the XML mappings).
I have a User object which currently looks like this:
public class User {
private Key key;
private Name name;
}
I need to add in Preferences for some of these users (we have two different types of users which share the same object).
public class Preferences {
private Person person; //The person key acts as our foreign and primary key
private Integer numToShow;
private String defaultScreenToShow;
}
My person XML is as such:
<hibernate-mapping package="com.example.entities">
<id key column="PERSON_ID" /> <!-- Leaving out custom generator -->
<!--
Not sure what the column needs to be here, as
preferences are in own table. Also read it has to
be a faked out many-to-one here as not all users will
have preferences.
-->
<many-to-one name="preferences" not-null="false" />
<component class="com.example.entities.Name">
<property column="first_name" name="first" />
<property column="last_name" name="last" />
</component>
</hibernate-mapping>
My preferences XML file is as such:
<hibernate-mapping package="com.example.entities">
<property column="default_screen" name="defaultScreenToShow" />
<property column="number_search_results" name="numToShow" />
<!-- Not sure what the ID needs to be here -->
</hibernate-mapping>
I'm pretty green with Hibernate in all honesty, but this seems like something which should be pretty easy to map in. I thought I had the mappings done properly, but I get a deserialization exception upon trying to load a person (I've marked the classes as Serializable -- to no avail).
Upvotes: 3
Views: 4321
Reputation: 9488
I was able to solve this in my desired way (Annotating the new class, and adding to the XML of the old class -- When I used XML in each situation, I was only able to store the Ordinal value of the enum, which wasn't desired).
Person.hbm.xml
<join table="PREFS_JOIN_TABLE" optional="true">
<key column="PERSON_ID" />
<many-to-one name="preferences" column="PREFERENCES_ID" not-null="true" unique="true" cascade="all"/>
</join>
My new class, which I was able to annotate, now looks like:
@Entity
@Table(name = "PREFERENCES")
public class UserPreferences implements Preferences {
private Long id;
private Panel defaultPanelToShow;
private Person person;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="prefSeq")
@SequenceGenerator(name="prefSeq", sequenceName = "SQ_PREFERENCES_ID", allocationSize = 10, initialValue = 1)
@Column(name="PREFERENCES_ID")
public Long getId() {
return id;
}
@Column(name="DEFAULT_USER_PANEL")
@Enumerated(EnumType.STRING)
public Panel getDefaultRequestPanel() {
return defaultPanelToShow;
}
@OneToOne
@JoinTable(name="PREFS_JOIN_TABLE", joinColumns=@JoinColumn(name="PREFERENCES_ID", unique=true), inverseJoinColumns=@JoinColumn(name="PERSON_ID", unique=true))
public Person getPerson() {
return person;
}
}
Upvotes: 1
Reputation: 179
Try mapping it as a composite id with only the one component.
Something like:
<composite-id name="col_name">
<key-many-to-one name="person" class="Person" column="person_col"/>
</composite-id>
Otherwise, you could just set it's value to be unique and use the hibernate's built in generated key while still being able to look up a single row based on Person.
Upvotes: 0
Reputation: 139931
Take a look at the Association Mappings chapter of the Hibernate reference documentation, as it explains several different ways to map all kinds of associations, depending on if the relationship is unidirectional or bidirectional, one-to-one, one-to-many, or many-to-many, and whether or not the association between the tables is direct or done through a join table.
Upvotes: 0