Hibernate: how do I code the mapping for a composite, unique key that isn't the primary key?

1.2k views Asked by At

I have a file where I'm counting votes. I want to limit each user to a single vote on a given competition. The user can return and change his/her vote, but it would update the choice of competitor in the competition.

I can't figure out how to do this using Hibernate mapping files. (The programming language is Java.)

I've looked at using composite-id, but I want to have a typical numeric primary key on this thing if I need it later. (I also couldn't figure out how to make that work! =)

Here's my mapping file from which I generate the model objects and SQL:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.example.project.model.db.Vote" table="vote">

        <id name="voteId" type="int">
            <meta attribute="scope-set">protected</meta>
            <meta attribute="use-in-equals">true</meta>
            <generator class="native" />
        </id>
        <many-to-one name="user" column="userId" unique="false" not-null="true" lazy="false"
            class="com.example.project.model.db.User"
        />
        <many-to-one name="competition" column="competitionId" unique="false" not-null="true" lazy="false"
            class="com.example.project.model.db.Competition"
        />
        <many-to-one name="competitor" column="competitorId" unique="false" not-null="true" lazy="false"
            class="com.example.project.model.db.Competitor"
        />
        <property name="dateAdded" type="date" not-null="true" />
    </class>
</hibernate-mapping>
3

There are 3 answers

3
MarkOfHall On

I think the constraint should be enforced on the database, not in your application code. At some point in the future the application you're writing may not be the only code running against this data, if another application doesn't enforce the same constraint the data is corrupted. It is also likely that the data and the data structure will out last your application code. Thus, I would argue that the right place to enforce this type of constraint is on the database.

1
Ram Reddy On

Change the mapping from Vote to User in the following way will resolve the issue. add unique="true" in the mapping should work.

0
CVS On

Implementation in database wont work in case of Hibernate using an embedded database(HSQL or H2).In such cases a unique key voilation would be thrown at runtime when hibenate accesses the model layer to implement its db structure.

Better use the primary key in a manner that satisfies unique=true.Vote up for @Ram