# Embeddable inheritance but still being able to reference specific terminal subtypes directly

**URL:** <https://discourse.hibernate.org/t/embeddable-inheritance-but-still-being-able-to-reference-specific-terminal-subtypes-directly/12315>\
**Category:** Hibernate ORM\
**Created:** [May 29, 2026, 7:09pm UTC](https://discourse.hibernate.org/t/embeddable-inheritance-but-still-being-able-to-reference-specific-terminal-subtypes-directly/12315 "2026-05-29T19:09:55Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![itshibernatingtime](https://avatars.discourse-cdn.com/v4/letter/i/a183cd/32.png) [@itshibernatingtime](https://discourse.hibernate.org/u/itshibernatingtime)\
**Post date:** [May 29, 2026, 7:09pm UTC](https://discourse.hibernate.org/t/embeddable-inheritance-but-still-being-able-to-reference-specific-terminal-subtypes-directly/12315/1 "2026-05-29T19:09:55Z")

</div>

Hello! Please ignore the weird model - it’s just to demonstrate.

I’m using Hibernate 6.6.45.

I have this discriminator-based embeddable hierarchy:

```auto
@Embeddable
@DiscriminatorColumn
public abstract class Car {

    @Column(nullable = false)
    private String color;

}

@Embeddable
@DiscriminatorValue("VW")
public class Volkswagen extends Car {

    @Column
    private Boolean electric;

}

@Embeddable
@DiscriminatorValue("TO")
public class Toyota extends Car {

    @Column
    private Integer numberOfWheels;

}

```

ParkingPlace supports different types of cars:

```auto
@Entity
public class ParkingPlace {

    @Id
    @GeneratedValue
    private Long id;

    @Embedded
    private Car car;

}

```

But VolkswagenDealer references the Volkswagen type directly - my expectation is that this should work without having a discriminator column:

```auto
@Entity
public class VolkswagenDealer {

    @Id
    @GeneratedValue
    private Long id;

    @Embedded
    private Volkswagen specialDeal;

}

```

Creating, persisting, reading ParkingPlace instances with different types of Car works perfectly.

But if I were to create and read back a VolkswagenDealer with its Volkswagen:

```auto
@Test
void terminalEmbeddableReferenceTest(SessionFactoryScope scope) throws Exception {
    scope.inTransaction(session -> {
        var pp = createVolkswagenDealer(session);
        Assertions.assertNotNull(pp.getId());

        session.flush();
        session.refresh(pp);

        Assertions.assertInstanceOf(Volkswagen.class, pp.getSpecialDeal());
        Assertions.assertEquals("red", pp.getSpecialDeal().getColor()); // FAILS HERE
        Assertions.assertEquals(true, pp.getSpecialDeal().getElectric());
    });
}

private VolkswagenDealer createVolkswagenDealer(Session session) {
    var vw = newVolkswagen();

    var dealer = new VolkswagenDealer();
    dealer.setSpecialDeal(vw);
    session.persist(dealer);

    return dealer;
}

private Volkswagen newVolkswagen() {
    var vw = new Volkswagen();
    vw.setColor("red");
    vw.setElectric(true);
    return vw;
}

```

It fails to persist and read the inherited Car#color property:

```auto
org.opentest4j.AssertionFailedError: 
Expected :red
Actual :null

```

If I try querying the same color property:

```auto
    @Test
    void terminalEmbeddableReferenceQueryTest(SessionFactoryScope scope) throws Exception {
        scope.inTransaction(session -> {
            var pp = createVolkswagenDealer(session);
            Assertions.assertNotNull(pp.getId());

            session.flush();

            var query = session.createQuery("SELECT DISTINCT vd.specialDeal.color FROM VolkswagenDealer vd");
            var result = query.getSingleResult();

            Assertions.assertEquals("red", result);
        });
    }

```

Again it fails, this time with:

```auto
java.lang.IllegalArgumentException: org.hibernate.query.sqm.UnknownPathException: Could not resolve attribute 'color' of 'org.hibernate.bugs.impl.embeddables.Volkswagen' [SELECT DISTINCT vd.specialDeal.color FROM VolkswagenDealer vd]

```

In fact if I look at the auto generated schema, you can see that the inherited color property is missing completely:

```auto
Hibernate: 
    create table VolkswagenDealer (
        id bigint not null,
        electric boolean,
        primary key (id)
    )

```

Is there any way to fix this, to achieve the model I want? I really want to preserve Java type compatibility and not introduce any more classes than I have to.

Thank you.

(Also posted at [https://stackoverflow.com/q/79948638/1341535](https://stackoverflow.com/q/79948638/1341535) with an expanded premise.)

---

<div class="post-metadata">

**Author:** ![itshibernatingtime](https://avatars.discourse-cdn.com/v4/letter/i/a183cd/32.png) [@itshibernatingtime](https://discourse.hibernate.org/u/itshibernatingtime)\
**Post date:** [June 1, 2026, 7:01am UTC](https://discourse.hibernate.org/t/embeddable-inheritance-but-still-being-able-to-reference-specific-terminal-subtypes-directly/12315/2 "2026-06-01T07:01:58Z")

</div>

Alternatively is there a way to have a `Car`-typed field, but instead of the `dtype` database column to specify a fixed type/discriminator value with an annotation on the field?

---

<div class="post-metadata">

**Author:** ![itshibernatingtime](https://avatars.discourse-cdn.com/v4/letter/i/a183cd/32.png) [@itshibernatingtime](https://discourse.hibernate.org/u/itshibernatingtime)\
**Post date:** [June 1, 2026, 7:04am UTC](https://discourse.hibernate.org/t/embeddable-inheritance-but-still-being-able-to-reference-specific-terminal-subtypes-directly/12315/3 "2026-06-01T07:04:40Z")

</div>

Sidenote: the user guide says:

> By default, the discriminator column will be `STRING` typed and named like `<property_name>_DTYPE`, where `property_name` is the name of the `@Embedded` property in the respective entity mapping.

But in reality it’s just `DTYPE`as you can see in the auto-generated schema:

```auto
Hibernate: 
    create table ParkingPlace (
        id bigint not null,
        DTYPE varchar(31) not null,
        color varchar(255) not null,
        numberOfWheels integer,
        electric boolean,
        primary key (id)
    )

```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [June 1, 2026, 10:39am UTC](https://discourse.hibernate.org/t/embeddable-inheritance-but-still-being-able-to-reference-specific-terminal-subtypes-directly/12315/4 "2026-06-01T10:39:32Z")

</div>

Hi and thanks for reporting the problem. Please try to create a reproducer with our [test case template](https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-7/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) and if you are able to reproduce the issue, create a bug ticket in our [issue tracker](https://hibernate.atlassian.net) and attach that reproducer.

---

<div class="post-metadata">

**Author:** ![itshibernatingtime](https://avatars.discourse-cdn.com/v4/letter/i/a183cd/32.png) [@itshibernatingtime](https://discourse.hibernate.org/u/itshibernatingtime)\
**Post date:** [June 3, 2026, 9:44am UTC](https://discourse.hibernate.org/t/embeddable-inheritance-but-still-being-able-to-reference-specific-terminal-subtypes-directly/12315/5 "2026-06-03T09:44:56Z")

</div>

I guess XML mapping could be the answer: map the discriminated hierarchy of embeddables under one set of names, and then again under different set of names with Car as a mapped superclass instead.

I’m not gonna introduce XML mapping just for this though… Resorting to this instead for now:

```auto
@Entity
public class VolkswagenDealer {

    @Id
    @GeneratedValue
    private Long id;

    @Embedded
    // We don't support other types of cars here, so let's remap their
    // properties to whatever in order to avoid introducing redundant DB fields
    @AttributeOverride(
        name = "numberOfWheels",
        column = @Column(name = "dtype", insertable = false, updatable = false)
    )
    private Car specialDeal;

    public Volkswagen getSpecialDeal() {
        return (Volkswagen) specialDeal;
    }

}

```

This isn’t great, but it’ll have to do.
