Будьте в спящем режиме, единственное поле наследования и использования таблицы от суперкласса как столбец различителя

У меня есть следующие виды классов для, в спящем режиме иерархия объекта. Я пытаюсь иметь два бетона sub классы Sub1Class и Sub2Class. Они разделяются столбцом различителя (field) это определяется в MappedSuperClass. Существует абстрактный класс объекта EntitySuperClass на который ссылаются другие объекты. Другие объекты не должны заботиться, ссылаются ли они на самом деле Sub1Class или Sub2Class.

Это это на самом деле возможное? В настоящее время я получаю эту ошибку (потому что определение столбца наследовано дважды в Sub1Class и в EntitySuperClass):

Repeated column in mapping for entity: my.package.Sub1Class column: field (should be mapped with insert="false" update="false")

Если я добавляю @MappedSuperClass кому: EntitySuperClass, затем я добираюсь, ошибка утверждения от будьте в спящем режиме: этому не нравится, если классом является и Объект и отображенный суперкласс. Если я удаляю @Entity от EntitySuperClass, класс больше не является объектом и не может быть сослан от других объектов:

MappedSuperClass часть внешнего пакета, поэтому если возможный он не должен быть изменен.

Мои классы:

@MappedSuperclass
public class MappedSuperClass {
    private static final String ID_SEQ = "dummy_id_seq";
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_SEQ)
    @GenericGenerator(name=ID_SEQ, strategy="sequence")

    @Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)
    private Integer id;

    @Column(name="field", nullable=false, length=8)
    private String field;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getField() {
        return field;
    }
    public void setField(String field) {
        this.field = field;
    }
}


@Entity
@Table(name = "ACTOR")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="field", discriminatorType=DiscriminatorType.STRING)
abstract public class EntitySuperClass extends MappedSuperClass {


    @Column(name="description", nullable=false, length=8)
    private String description;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

@Entity
@DiscriminatorValue("sub1")
public class Sub1Class extends EntitySuperClass {

}


@Entity
@DiscriminatorValue("sub2")
public class Sub2Class extends EntitySuperClass {

}


@Entity
public class ReferencingEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer id;

    @Column
    private Integer value;

    @ManyToOne
    private EntitySuperClass entitySuperClass;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getValue() {
        return value;
    }

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

    public EntitySuperClass getEntitySuperClass() {
        return entitySuperClass;
    }

    public void setEntitySuperClass(EntitySuperClass entitySuperClass) {
        this.entitySuperClass = entitySuperClass;
    }

}
9
задан Juha Syrjälä 14 July 2010 в 10:35
поделиться

3 ответа

В моем проекте это делается так:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "field", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("dummy")
public class EntitySuperClass {
    // here definitions go 
    // but don't define discriminator column here
}

@Entity
@DiscriminatorValue(value="sub1")
public class Sub1Class extends EntitySuperClass {
    // here definitions go
}

И работает. Я думаю, ваша проблема в том, что вы без нужды определяете поле дискриминатора в своем определении суперкласса. Удалите его, и он будет работать.

16
ответ дан 4 December 2019 в 07:13
поделиться

Чтобы использовать столбец дискриминатора как обычное свойство, вы должны сделать это свойство доступным только для чтения с помощью insertable = false, обновляемый = false . Поскольку вы не можете изменить MappedSuperClass , вам необходимо использовать @AttributeOverride :

@Entity 
@Table(name = "ACTOR") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="field", discriminatorType=DiscriminatorType.STRING) 

@AttributeOverride(name = "field", 
    column = @Column(name="field", nullable=false, length=8, 
        insertable = false, updatable = false))

abstract public class EntitySuperClass extends MappedSuperClass { 
    ...
}
13
ответ дан 4 December 2019 в 07:13
поделиться

Вы можете отобразить столбец базы данных только один раз как поле для чтения-записи (поле, которое имеет insertable=true и/или updatable=true) и любое количество раз как поле только для чтения (insertable=false и updatable=false). Использование колонки как @DiscriminatorColumn считается отображением чтение-запись, поэтому вы не можете иметь дополнительные отображения чтение-запись.

Hibernate будет устанавливать значение, указанное в @DiscriminatorColumn за кулисами, основываясь на конкретном экземпляре класса. Если бы вы могли изменить это поле, это позволило бы модифицировать поле @DiscriminatorColumn так, чтобы ваш подкласс и значение в поле могли не совпадать.

2
ответ дан 4 December 2019 в 07:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: