unable to find column with logical name of @embedd

2019-08-08 14:44发布

问题:

In a Spring MVC app using hibernate and JPA, I am trying to set up a mapping for an entity whose underlying data table has a two-column primary key. How can I alter my code below to get it to work?

I created an EmbeddedId called conceptPK, but I am getting the following error message:

Caused by: org.hibernate.MappingException: 
Unable to find column with logical name: conceptPK 
in org.hibernate.mapping.Table(sct2_concept) and its related supertables and secondary tables

In the entity class, I set up the primary key with the following code:

@EmbeddedId
@AttributeOverrides({
    @AttributeOverride(name="id", column=@Column(name="id")),
    @AttributeOverride(name="effectiveTime", column=@Column(name="effectiveTime"))
})
private ConceptPK conceptPK;

The embedded ConceptPK class is as follows:

@Embeddable
class ConceptPK implements Serializable {
    @Column(name="id", nullable=false)
    protected BigInteger id;

    @Column(name="effectiveTime", nullable=false)
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    private DateTime effectiveTime;

    /** getters and setters **/
    public DateTime getEffectiveTime(){return effectiveTime;}
    public void setEffectiveTime(DateTime ad){effectiveTime=ad;}

    public void setId(BigInteger id) {this.id = id;}
    public BigInteger getId() {return id;}
}

For easier reading, I have uploaded the complete code and the complete stack trace to a file sharing site rather than create an excessively long posting here.

You can read the complete code for the class above at the file sharing site by clicking on this link.

You can read the code for a second class that references the first class at this link.

You can read the code for a third class that references the first class at this link.

You can read the SQL code that creates the underlying data tables by clicking on this link.

You can read the complete stack trace at the file sharing site by clicking on this link.

回答1:

The problem is the SnomedDescription Entity's @ManyToOne association to SnomedConcept.

For a start, this is not a ManyToOne, but in fact a OneToOne, as their primary keys are identical.

But the main problem is that the columns you've used in the @JoinColumn annotation for this association do not exist as database columns, so this will never work.

Instead, you should have join columns as follows:

@ManyToOne
@JoinColumns({
    @JoinColumn(name="id", referencedColumnName="id"),
    @JoinColumn(name="effectiveTime", referencedColumnName="effectiveTime")
})
private SnomedConcept concept;

Now, you can carry on using the @ManyToOne for this relationship, but really you should be using the same embedded PK for both (ConceptPK), and then SnomedDescription will look more like:

@Entity
@Table(name = "accesslogs")
public class SnomedDescription {

    @EmbeddedId
    private ConceptPK descriptionPK;

    @Column(name="active")
    private boolean active;

    @Column(name="moduleId")
    private BigInteger moduleid;

    @OneToOne
    @PrimaryKeyJoinColumn
    private SnomedConcept concept;

    ..... etc.

Yes, you can use the same PK embeddable in multiple Entities.

If it is a one-to-one relationship, then the association in SnomedConcept to SnomedDescription should also be one-to-one, with @PrimaryKeyJoinColumn.

If the association between the two is optional, then the 'side' that is always there should define the one-to-one as @OneToOne(optional=true). In other words, if there is always a Concept, but not always a Description, then the one-to-one in Concept should be defined as @OneToOne(optional=true).



回答2:

Annotating the key as hown below solved the issue for me.

@Column(name = "name", nullable = false)
String name;