OneToMany with inherited classes on both sides

Hi,

I am having trouble getting this mapping to work.

I have two base classes, company and computer_system. Each of the base classes has two subclasses, and they use the InheritanceType.JOINED strategy.

Each computer system has a company owner. A customer_computer_system is owned by a customer_company and a distributor_computer_system is owned by a distributor_company.

@Entity ...
@Inheritance(strategy= InheritanceType.JOINED)
public abstract class ComputerSystem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "OWNER_ID", foreignKey = @ForeignKey())
    protected Company owner;
}

One of the company subclasses has a OneToMany collection with one of the computer_system subclasses. I started by annotating my collection this way:

@Entity ...
public class Customer {
    @OneToMany(mappedBy = "owner", orphanRemoval = true, cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    private List<CustomerComputerSystem> computerSystems;
}

The trouble is that hibernate expects the owner field to be in the customer_computer_system table - instead the owner field is in the base class, computer_system. So hibernate wants to create an owner field in customer_computer_system.

I tried to explicitly describe the join table this way:

@Entity ...
public class Customer {
    @OneToMany(orphanRemoval = true, cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinTable(name = "computer_system", joinColumns = { @JoinColumn(name = "OWNER_ID") }, inverseJoinColumns = { @JoinColumn(name = "id") })
    private List<CustomerComputerSystem> computerSystems;
}

With that change, the OneToMany collection succeeded, but now the schema tool wants to create a foreign key constraint from computer_system to customer_computer_system. That would be incorrect, as not all computer_systems are customer_computer_systems.

alter table computer_system add constraint FKqwc8n7tsusito0tmeeos68k5c foreign key (id) references customer_computer_system (id);

In order to not create that bad FK constraint, I tried expanding my @JoinTable annotations with foreignKey = @ForeignKey(name = "none"). Unfortunately that didn’t help.

Any ideas?

(version 6.3.0-SNAPSHOT)

This mapping looks ok to me

@Entity
@Inheritance(strategy= InheritanceType.JOINED)
public abstract class ComputerSystem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "OWNER_ID")
    protected Company owner;
}

@Entity
public class Customer {
    @OneToMany(mappedBy = "owner", orphanRemoval = true, cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    private List<CustomerComputerSystem> computerSystems;
}

The trouble is that hibernate expects the owner field to be in the customer_computer_system table - instead the owner field is in the base class, computer_system. So hibernate wants to create an owner field in customer_computer_system.

What do you mean by “wants to create an owner field”?

Forget about the join table stuff, that’s not appropriate for this mapping.

By “wants to create an owner field” I mean that the schema migrator tool produces this script:

alter table customer_computer_system add column OWNER_ID bigint;
alter table distributor_computer_system add column OWNER_ID bigint;

I’m happy to discover that using the simple mapping works, even though the schema tool complains.

Ok that looks like a bug :slight_smile:
Please create an issue in the issue tracker(https://hibernate.atlassian.net) with a test case(hibernate-test-case-templates/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java at main · hibernate/hibernate-test-case-templates · GitHub) that reproduces the issue.