Jerome Cance
Jerome Cance

Reputation: 8183

hibernate and generic field mapping

I want to map a generic field in a superclass with Hibernate.

My mother class is :

@Entity
@Table(name = "ParameterValue")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "parameterType", discriminatorType = DiscriminatorType.STRING)
public abstract class ParameterValue<C>
{
    private C value;

    /* HELP NEEDED HERE */
    public C getValue()
    {
        return value;
    }

    public void setValue(C value)
    {
        this.value = value;
    }
}

One subclass :

@Entity
@DiscriminatorValue(value = "integer")
@AttributeOverride(name = "value", column = @Column(name = "intValue"))
public class IntegerParameterValue extends ParameterValue<Integer>
{
}

As you can see I override the value field to specify what column to use in the database. My table ParameterValue is composed of several column, one for each type.

CREATE TABLE `ParameterValue` (
    `intValue` int(11) DEFAULT NULL,
    `doubleValue` double DEFAULT NULL,
    `stringValue` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

But hibernate complains that :

ParameterValue.value has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type

Ok, but what's the good configuration for getValue in the superclass ? (I've put a comment with "HELP NEEDED HERE")

Upvotes: 2

Views: 4958

Answers (1)

JB Nizet
JB Nizet

Reputation: 691715

I'm pretty sure you can't map a single Java attribute to three different columns. You will have to use this:

@Entity
@Table(name = "ParameterValue")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "parameterType", discriminatorType = DiscriminatorType.STRING)
public abstract class ParameterValue<C> {
    public abstract C getValue();

    public abstract void setValue(C value);
}

@Entity
@DiscriminatorValue(value = "integer")
public class IntegerParameterValue extends ParameterValue<Integer> {
    @Column(name = "intValue")
    private Integer intValue;

    @Override
    public Integer getValue() {
        return intValue;
    }

    @Override
    public void setValue(Integer value) {
        this.intValue = value;
    }
}

Upvotes: 6

Related Questions