1

我想将现有数据库(我们现在无法更改)映射到 Hibernate 实体。但是我的映射似乎有一个我无法克服的传递映射复合键的问题。

FluidSampleLabel 将 FluidSample 作为外键并作为其自己的复合主键的一部分。Hibernate 似乎忽略了 FluidSampleLabel 中嵌入外键实体 FluidSample 映射的列/嵌入 id。

Github 上的测试项目: https ://github.com/burka/hibernate-transitive-compkey-problem.git

org.hibernate.AnnotationException: A Foreign key refering compkey_problem.model.FluidSample from compkey_problem.model.FluidSampleLabel has the wrong number of column. should be 1

如果嵌入式 fks 上没有@ManyToOne带注释的命名列,我会收到以下错误:

Caused by: org.hibernate.MappingException: Foreign key (FK246FD874D0837E3B:fluid_sample_label [sample])) must have same number of columns as the referenced primary key (fluid_sample [sampleGroup,pre_post])
create sequence sample_group_seq start 10000;

create table sample_group (
sample_group_id int primary key,
payload varchar(200)
);

create table fluid_sample (
sample_group_id int not null,
pre_post varchar(20) not null check ( pre_post in ( 'PRE', 'POST') ),
amount number(20,10) not null,
primary key ( sample_group_id, pre_post ),
constraint fk_fluid_sample_group foreign key ( sample_group_id ) references sample_group ( sample_group_id )
);

create table fluid_sample_label (
sample_group_id int,
pre_post varchar(20) not null check ( pre_post in ( 'PRE', 'POST') ),
label varchar(200) not null,
primary key ( sample_group_id, pre_post, label ),
constraint fk_fluid_label_fluid foreign key ( sample_group_id, pre_post ) references fluid_sample ( sample_group_id, pre_post )
);
@Entity
@SequenceGenerator(name = "sampleGroupSequence", sequenceName = "sample_group_seq", allocationSize = 1)
@Table(name = "sample_group")
public class SampleGroup
{
    @Id
    @GeneratedValue(generator = "sampleGroupSequence", strategy = GenerationType.SEQUENCE)
    @Column(name = "sample_group_id")
    private Integer sampleGroupId;

    @OneToMany(mappedBy = "sampleGroup")
    private List<FluidSample> fluidSamples = new ArrayList<>();

    @Column(name = "payload")
    private String payload;

    public SampleGroup()
    {
    }

    public FluidSample addNewPreFluidSample()
    {
        FluidSample sample = new FluidSample(this, PrePost.PRE);
        this.fluidSamples.add(sample);
        return sample;
    }
}


@Entity
@Table(name = "fluid_sample")
public class FluidSample
{
    @Id
            @ManyToOne
            @JoinColumn(name = "sample_group_id")
    private SampleGroup sampleGroup;

    @Id
    @Column(name = "pre_post")
    @Enumerated(EnumType.STRING)
    private PrePost prePost;

    @OneToMany(mappedBy = "sample")
    private List<FluidSampleLabel> labels = new ArrayList<>();

    @Column(name = "amount")
    private BigDecimal amount;

    @SuppressWarnings("unused")
    private FluidSample()
    {
    }

    public FluidSample(SampleGroup sampleGroup, PrePost prePost)
    {
        this.sampleGroup = sampleGroup;
        this.prePost = prePost;
    }

    public FluidSampleLabel addNewLabel(String value)
    {
        FluidSampleLabel label = new FluidSampleLabel(this, value);
        this.labels.add(label);
        return label;
    }
}

@Entity
@Table(name = "fluid_sample_label")
public class FluidSampleLabel
{
    @Id
            @ManyToOne
            @JoinColumns({ @JoinColumn(name = "sample_group_id"), @JoinColumn(name = "pre_post")})
    private FluidSample sample;

    @Id
    private String value;

    @SuppressWarnings("unused")
    private FluidSampleLabel()
    {
    }

    FluidSampleLabel(FluidSample sample, String value)
    {
        this.sample = sample;
        this.value = value;
    }

    public String getValue()
    {
        return this.value;
    }
}



public enum PrePost
{
    PRE, POST;
}
4

0 回答 0