0

Details below but the short version is: I have a column user_id on a PostgreSQL table called config. That column is referenced using @Column(name = "user_id") but when my server starts, the EntityManagerFactory can't be built because:

Caused by: org.hibernate.HibernateException: Missing column: userId in public.config
    at org.hibernate.mapping.Table.validateColumns(Table.java:366)
    at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1305)
    at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:512)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1797)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
    ... 31 more

So it seems like I'm missing something here that is causing Hibernate to look for a userId column instead of a column called user_id.

Details:

The table definition:

CREATE TABLE config
(
  user_id character varying(255) NOT NULL,
  application_id integer NOT NULL,
  step_id integer NOT NULL,
  prompt_id integer NOT NULL,
  default_value character varying(255),
  CONSTRAINT "PK_Config" PRIMARY KEY (user_id, application_id, step_id, prompt_id),
  CONSTRAINT "FK_Config_User" FOREIGN KEY (user_id)
      REFERENCES app_user (user_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE config
  OWNER TO appuser;

The Hibernate entity is defined as:

// ...

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;

@Entity
@Table(name = "config")
@IdClass(ConfigId.class)
public class Config {

    private String userId;
    private Integer applicationId;
    private Integer stepId;
    private Integer promptId;
    private String defaultValue;

    @Id
    @Column(name = "user_id")
    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    @Id
    @Column(name = "application_id")
    public Integer getApplicationId() {
        return applicationId;
    }

    public void setApplicationId(Integer applicationId) {
        this.applicationId = applicationId;
    }

    @Id
    @Column(name = "step_id")
    public Integer getStepId() {
        return stepId;
    }

    public void setStepId(Integer stepId) {
        this.stepId = stepId;
    }

    @Id
    @Column(name = "prompt_id")
    public Integer getPromptId() {
        return promptId;
    }

    public void setPromptId(Integer promptId) {
        this.promptId = promptId;
    }

    @Column(name = "default_value", columnDefinition = "nvarchar")
    public String getDefaultValue() {
        return defaultValue;
    }

    public void setDefaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
    }

}

Where ConfigId is defined as:

// ...

public class ConfigId implements Serializable{

    private static final long serialVersionUID = -5372509566187824168L;

    private String userId;
    private Integer applicationId;
    private Integer stepId;
    private Integer promptId;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public Integer getApplicationId() {
        return applicationId;
    }

    public void setApplicationId(Integer applicationId) {
        this.applicationId = applicationId;
    }

    public Integer getStepId() {
        return stepId;
    }

    public void setStepId(Integer stepId) {
        this.stepId = stepId;
    }

    public Integer getPromptId() {
        return promptId;
    }

    public void setPromptId(Integer promptId) {
        this.promptId = promptId;
    }

    @Override
    public int hashCode() {
       // ...
    }

    @Override
    public boolean equals(Object obj) {
       // ...
    }
}
Chris Williams
  • 11,647
  • 15
  • 60
  • 97

3 Answers3

0

You are missing composite-key in your code. This example has been explained brilliantly: Composite-Key and Hibernate

Community
  • 1
  • 1
Paweł Głowacz
  • 2,926
  • 3
  • 18
  • 25
  • I read through that answer and it looks like I've done all of that using the `@IdClass` annotation. Did you see something specific that I'm missing? – Chris Williams Aug 17 '15 at 19:07
0

Crap. I had another entity that referenced my Config entity with @JoinColumn(name = "userId"). I was able to fix that and everything works now. I really wish the error message had been more clear as to where "userId" was coming from.

Chris Williams
  • 11,647
  • 15
  • 60
  • 97
0

I was having the exact same problem. My issue seemed to be a mix usage of where the @column annotations were defined.

In my entity class, @column annotations where defined at the getter method. When creating my @Embeddable class for my composite id, the @column annotations were defined at the field level. I made sure all my @Column annotations were at my getter methods and all started working.

Micho Rizo
  • 1,000
  • 3
  • 12
  • 27