user209627
user209627

Reputation:

@IdClass with non primative @Id

I'm trying to add a composite primary key to a class and having a bit of trouble. Here are the classes.

class User {
    private long id;
    ...
}

class Token {
    private User user;
    private String series;
    ...
}

I'm using the orm.xml to map the classes because they're actually part of a higher level API that I don't want to depend on JPA - it has a number of implementations.

Here it is:

...
<entity class="User">
    <attributes>
        <id name="id">
            <generated-value strategy="AUTO"/>
        </id>
        ...
    </attributes>
</entity>

<entity class="Token">
    <id-class class="TokenPK"/>
    <attributes>
        <id name="series"/>
        <id name="user"/>
        <many-to-one name="user"/>
    </attributes>
</entity>

Finally to make it all work, I've created the TokenPK class and it looks like this:

public class TokenPK implements Serializable {

    private String series;
    private User user;

    public TokenPK() {
    }

    public TokenPK(String series, User user) {
        this.series = series;
        this.user = user;
    }

    public String getSeries() {
        return series;
    }

    public void setSeries(String series) {
        this.series = series;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        RememberMeTokenPK that = (TokenPK) o;

        if (!series.equals(that.series)) return false;
        if (!user.equals(that.user)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = series.hashCode();
        result = 31 * result + user.hashCode();
        return result;
    }
}

The problem I'm having is that Hibernate is complaning that it can't create the mysql tables because 'BLOB/TEXT column 'user' used in key specification without a key length'.

My issue is actually that the columns are being stored as BLOBs in the first place. Until I put the id-class in it was working just fine, user was linked via it's id. How can I make Hibernate use the long value for the user's id it was using as the primary key?

Updated orm.xml:

<entity class="Token">
    <id-class class="TokenPK"/>
    <attributes>
        <id name="series"/>
        <id name="user">
            <column name="userId"/>
        </id>
        <many-to-one name="user">
            <join-column name="userId" insertable="false" updatable="false"/>
        </many-to-one>
    </attributes>
</entity>

Upvotes: 6

Views: 3013

Answers (1)

Bozho
Bozho

Reputation: 597106

Define the composite key with String series and int userId, and specify a join-column id for the User in Token. I think you will also have to add insertable="false", updatable="false".

 <composite-id name="TikenPK" class="yourpackage.TokenPK"> 
        <key-property name="series" column="series" type="string" />
        <key-property name="userId" column="userId" type="integer"/>
       </composite-id> 

Upvotes: 2

Related Questions