简体   繁体   English

为什么JPA在insert语句中使用不正确的列名

[英]why is JPA using incorrect column name in insert statement

I am trying to insert a record into a table using the JPA. 我正在尝试使用JPA将记录插入表中。 I get an error from postgres that a column name is incorrect. 我从postgres收到一个错误,指出列名不正确。 The column in question is a foreign key to another table. 有问题的列是另一个表的外键。

Internal Exception: org.postgresql.util.PSQLException: ERROR: column "location_id" of relation "device" does not exist
  Position: 125
Error Code: 0
Call: INSERT INTO public.device (ASSETMGR, CIIM, CREATEDDATE, ISDISPOSED, MODIFIEDDATE, NDV, PARTNUMBER, SERIALNUMBER, TAGNUMBER, LOCATION_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

What I expected is for the insert statement to use 'location' not 'location_id' and in fact I double checked to see if there was a 'location_id' column name specified in the project and could not find one. 我期望的是insert语句使用“ location”而不是“ location_id”,并且实际上我再次检查了项目中是否指定了“ location_id”列名称,但找不到。 I use lowercase for all column names in the database. 我对数据库中的所有列名都使用小写。

Can someone point to why the JPA infrastructure is trying to insert into a field that doesn't exist in code? 有人可以指出为什么JPA基础结构试图插入到代码中不存在的字段中吗? Thanks! 谢谢!

Here's the Device class: 这是Device类:

@MappedSuperclass
public abstract class AbstractDevice implements java.io.Serializable
{

    // Fields

    /**
     * 
     */
    private static final long serialVersionUID = 7363521382735742845L;
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY )
    private Integer id;
    private Integer ciim;
    private Integer assetmgr;
    private String serialnumber;
    private String partnumber;
    private String tagnumber;
    private Timestamp createddate;
    private Timestamp modifieddate;
    private Integer ndv;
    private Location location;
    private Boolean isdisposed;
    private Set<LocationReport> locationReports = new HashSet<LocationReport>(0);

    // Constructors

    /** default constructor */
    public AbstractDevice()
    {
    }

    /** minimal constructor */
    public AbstractDevice(Integer id, String serialnumber,
            Timestamp createddate, Timestamp modifieddate, Boolean isdisposed)
    {
        this.id = id;
        this.serialnumber = serialnumber;
        this.createddate = createddate;
        this.modifieddate = modifieddate;
        this.isdisposed = isdisposed;
    }

    /** full constructor */
    public AbstractDevice(Integer id, Location location, Integer ciim,
            Integer assetmgr, String serialnumber, String partnumber,
            String tagnumber, Timestamp createddate, Timestamp modifieddate,
            Integer ndv, Boolean isdisposed, Set<LocationReport> locationReports)
    {
        this.id = id;
        this.location = location;
        this.ciim = ciim;
        this.assetmgr = assetmgr;
        this.serialnumber = serialnumber;
        this.partnumber = partnumber;
        this.tagnumber = tagnumber;
        this.createddate = createddate;
        this.modifieddate = modifieddate;
        this.ndv = ndv;
        this.isdisposed = isdisposed;
        this.locationReports = locationReports;
    }

    // Property accessors

    @Column(name = "id", unique = true, nullable = false)
    public Integer getId()
    {
        return this.id;
    }

    public void setId(Integer id)
    {
        this.id = id;
    }

    @Column(name = "ciim")
    public Integer getCiim()
    {
        return this.ciim;
    }

    public void setCiim(Integer ciim)
    {
        this.ciim = ciim;
    }

    @Column(name = "assetmgr")
    public Integer getAssetmgr()
    {
        return this.assetmgr;
    }

    public void setAssetmgr(Integer assetmgr)
    {
        this.assetmgr = assetmgr;
    }

    @Column(name = "serialnumber", unique = true, nullable = false, length = 32)
    public String getSerialnumber()
    {
        return this.serialnumber;
    }

    public void setSerialnumber(String serialnumber)
    {
        this.serialnumber = serialnumber;
    }

    @Column(name = "partnumber", length = 128)
    public String getPartnumber()
    {
        return this.partnumber;
    }

    public void setPartnumber(String partnumber)
    {
        this.partnumber = partnumber;
    }

    @Column(name = "tagnumber", length = 16)
    public String getTagnumber()
    {
        return this.tagnumber;
    }

    public void setTagnumber(String tagnumber)
    {
        this.tagnumber = tagnumber;
    }

    @Column(name = "createddate", nullable = false, length = 29)
    public Timestamp getCreateddate()
    {
        return this.createddate;
    }

    public void setCreateddate(Timestamp createddate)
    {
        this.createddate = createddate;
    }

    @Column(name = "modifieddate", nullable = false, length = 29)
    public Timestamp getModifieddate()
    {
        return this.modifieddate;
    }

    public void setModifieddate(Timestamp modifieddate)
    {
        this.modifieddate = modifieddate;
    }

    @Column(name = "ndv")
    public Integer getNdv()
    {
        return this.ndv;
    }

    public void setNdv(Integer ndv)
    {
        this.ndv = ndv;
    }

    @Column(name = "isdisposed", nullable = false)
    public Boolean getIsdisposed()
    {
        return this.isdisposed;
    }

    public void setIsdisposed(Boolean isdisposed)
    {
        this.isdisposed = isdisposed;
    }


    @Column(name = "location")
    @ManyToOne( cascade = CascadeType.ALL )
    public Location getLocation()
    {
        return this.location;
    }

    public void setLocation( Location location )
    {
        this.location = location;
    }

    public Set<LocationReport> getLocationReports()
    {
        return this.locationReports;
    }

    public void setLocationReports(Set<LocationReport> locationReports)
    {
        this.locationReports = locationReports;
    }

    @Override
    public String toString()
    {
        return "AbstractDevice [id=" + id + ", ciim=" + ciim + ", assetmgr="
                + assetmgr + ", serialnumber=" + serialnumber + ", partnumber="
                + partnumber + ", tagnumber=" + tagnumber + ", createddate="
                + createddate + ", modifieddate=" + modifieddate + ", ndv="
                + ndv + ", locationReports=" + locationReports + "]";
    }

Here's the DDL for the device table: 这是设备表的DDL:

CREATE TABLE device
(
  ciim integer, -- Corresponding CIIM table id.
  assetmgr integer, -- Corresponding asset manager record identifier.
  serialnumber character varying(32) NOT NULL, -- A unique hardware identifier identifying this particular piece of equipment among all others from the same vendor.
  partnumber character varying(128), -- Vendor supplied part number defining this particular type of unit.
  tagnumber character varying(16), -- Tag identifier that identifies the asset for capital management purposes. Can be null and can be duplicated among different serial numbers.
  createddate timestamp without time zone NOT NULL DEFAULT now(),
  modifieddate timestamp without time zone NOT NULL DEFAULT now(),
  ndv integer DEFAULT nextval('device_seq'::regclass), -- foreign key to the device table in the NDV db
  id serial NOT NULL,
  location integer, -- fkey to location table
  isdisposed boolean NOT NULL DEFAULT false,
  CONSTRAINT device_pkey PRIMARY KEY (id),
  CONSTRAINT device_location_fkey FOREIGN KEY (location)
      REFERENCES location (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT "DEVICE_SERIAL_U" UNIQUE (serialnumber)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE device
  OWNER TO postgres;
COMMENT ON COLUMN device.ciim IS 'Corresponding CIIM table id.';
COMMENT ON COLUMN device.assetmgr IS 'Corresponding asset manager record identifier.
';
COMMENT ON COLUMN device.serialnumber IS 'A unique hardware identifier identifying this particular piece of equipment among all others from the same vendor. ';
COMMENT ON COLUMN device.partnumber IS 'Vendor supplied part number defining this particular type of unit.';
COMMENT ON COLUMN device.tagnumber IS 'Tag identifier that identifies the asset for capital management purposes. Can be null and can be duplicated among different serial numbers.';
COMMENT ON COLUMN device.ndv IS 'foreign key to the device table in the NDV db';
COMMENT ON COLUMN device.location IS 'fkey to location table';


-- Index: device_serialnumber_idx

-- DROP INDEX device_serialnumber_idx;

CREATE INDEX device_serialnumber_idx
  ON device
  USING btree
  (serialnumber COLLATE pg_catalog."default");

-- Index: fki_device_location_fkey

-- DROP INDEX fki_device_location_fkey;

CREATE INDEX fki_device_location_fkey
  ON device
  USING btree
  (location);

This is the primary key column for AbstractLocation.java which is what device.location is a foreign key to. 这是AbstractLocation.java的主键列,device.location是其外键。

@MappedSuperclass
public abstract class AbstractLocation implements java.io.Serializable
{

    // Fields

    /**
     * 
     */
    private static final long serialVersionUID = -8336411995952512794L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY )
    private Integer id;
    @Column( name="building

It looks like you are getting a default OneToOne mapping for the AbstractDevice.location field. 看来您正在为AbstractDevice.location字段获取默认的OneToOne映射。 The default JoinColumn.name value, as defined by the JPA spec, is JPA规范定义的默认JoinColumn.name值为

The concatenation of the following: the name of the referencing relationship property or field of the referenc- ing entity or embeddable class; 以下内容的串联:引用关系属性的名称或引用实体或可嵌入类的字段; "_"; “ _”; the name of the referenced primary key column. 引用的主键列的名称。

In this situation, the default is location_id . 在这种情况下,默认值为location_id

To change this, you must specify a JoinColumn : 要更改此设置,必须指定JoinColumn

@JoinColummn(name="location")
private Location location;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM