Hibernate JPA 2.0,Spring,Postgres - 例外:列索引超出范围

时间:2016-10-29 22:21:22

标签: java spring postgresql hibernate jpa

我正在使用带有PostgreSQL数据库的Hibernate 3.6。我使用@IdClass与复合键映射了一对多关系。当我在拥有实体上调用SaveOrUpdate时,当hibernate尝试插入子关系时,我收到异常。

例外是:

org.postgresql.util.PSQLException: The column index is out of range: 4, number of columns: 3.
at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:56)
at org.postgresql.core.v3.SimpleParameterList.setNull(SimpleParameterList.java:141)
at org.postgresql.jdbc2.AbstractJdbc2Statement.setNull(AbstractJdbc2Statement.java:1215)
at org.postgresql.jdbc3.AbstractJdbc3Statement.setNull(AbstractJdbc3Statement.java:1490)
at org.postgresql.jdbc4.AbstractJdbc4Statement.setNull(AbstractJdbc4Statement.java:84)
at com.zaxxer.hikari.proxy.PreparedStatementJavassistProxy.setNull(PreparedStatementJavassistProxy.java)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:78)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:283)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:278)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:317)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2195)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2431)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2875)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)

...

失败的实体看起来像这样(它包括在@IdClass中注释的类):

@Entity
@IdClass(DsbRowDataDashboard.RowDataDashboardPK.class)
@Table(name = "dsb_row_data_dashboard")
public class DsbRowDataDashboard implements Serializable {
    private static final long serialVersionUID = 2036988934943807608L; 

    public static final String NQ_GetRowsInvolvedForWorkstreamMoveUp = "DsbRowDataDashboard.getRowsInvolvedForWorkstreamMoveUp";
    public static final String NQ_GetRowsInvolvedForWorkstreamMoveDown = "DsbRowDataDashboard.getRowsInvolvedForWorkstreamMoveDown";
    public static final String NQ_GetRowsInvolvedForSubtaskMoveUp = "DsbRowDataDashboard.getRowsInvolvedForSubtaskMoveUp";
    public static final String NQ_GetRowsInvolvedForSubtaskMoveDown = "DsbRowDataDashboard.getRowsInvolvedForSubtaskMoveDown";
    public static final String NQ_FindMaxPositionForWorkstream = "DsbRowDataDashboard.findMaxPositionForWorkstream";
    public static final String NQ_FindMaxPositionForSubtask = "DsbRowDataDashboard.findMaxPositionForSubtask";

    @Id
    @Column(name = "row_data_id", insertable = false, updatable = false)
    private Long rowDataId;

    @Id
    @Column(name = "dashboard_id", insertable = false, updatable = false)
    private Long dashboardId;

    @Column(name = "row_position")
    private Long position;

    @ManyToOne// DO NOT cascade anything here
    @JoinColumn(name = "row_data_id")
    private DsbRowData rowData;

    @ManyToOne // DO NOT cascade anything here
    @JoinColumn(name = "dashboard_id")
    private DsbDashboard dashboard;

    public DsbRowDataDashboard() {
    }

    public DsbRowDataDashboard(DsbRowData rowData, DsbDashboard dsbDashboard, Long position) {
        this.rowData = rowData;
        this.dashboard = dsbDashboard;
        this.position = position;
    }

    public Long getRowDataId() {
        return rowDataId;
    }

    public void setRowDataId(Long rowDataId) {
        this.rowDataId = rowDataId;
    }

    public Long getDashboardId() {
        return dashboardId;
    }

    public void setDashboardId(Long dashboardId) {
        this.dashboardId = dashboardId;
    }

    public Long getPosition() {
        return position;
    }

    public void setPosition(Long position) {
        this.position = position;
    }

    public DsbRowData getRowData() {
        return rowData;
    }

    public void setRowData(DsbRowData rowData) {
        this.rowData = rowData;
    }

    public DsbDashboard getDashboard() {
        return dashboard;
    }

    public void setDashboard(DsbDashboard dashboard) {
        this.dashboard = dashboard;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((rowDataId == null) ? 0 : rowDataId.hashCode());
        result = prime * result + ((dashboardId == null) ? 0 : dashboardId.hashCode());
        result = prime * result + ((position == null) ? 0 : position.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof DsbRowDataDashboard))
            return false;
        DsbRowDataDashboard other = (DsbRowDataDashboard) obj;
        if (rowDataId == null) {
            if (other.rowDataId != null)
                return false;
        } else if (!rowDataId.equals(other.rowDataId))
            return false;
        if (dashboardId == null) {
            if (other.dashboardId != null)
                return false;
        } else if (!dashboardId.equals(other.dashboardId))
            return false;
        if (position == null) {
            if (other.position != null)
                return false;
        } else if (!position.equals(other.position))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "DsbRowDashboard [rowDataid=" + rowDataId + ", dashboardId = " + dashboardId + "position=" + position + "]";
    }

    public static class RowDataDashboardPK implements Serializable {
        private static final long serialVersionUID = -1665119146485718132L;

        protected Long rowDataId;
        protected Long dashboardId;

        public RowDataDashboardPK() {
        }

        public RowDataDashboardPK(Long rowDataId, Long dashboardId) {
            this.rowDataId = rowDataId;
            this.dashboardId = dashboardId;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((rowDataId == null) ? 0 : rowDataId.hashCode());
            result = prime * result + ((dashboardId == null) ? 0 : dashboardId.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (!(obj instanceof RowDataDashboardPK))
                return false;
            RowDataDashboardPK other = (RowDataDashboardPK) obj;
            if (rowDataId == null) {
                if (other.rowDataId != null)
                    return false;
            } else if (!rowDataId.equals(other.rowDataId))
                return false;
            if (dashboardId == null) {
                if (other.dashboardId != null)
                    return false;
            } else if (!dashboardId.equals(other.dashboardId))
                return false;
            return true;
        }
    }

}

父母的关系如下:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "rowData", orphanRemoval = true)
@Cascade({CascadeType.ALL})
private Set<DsbRowDataDashboard> rowPositions = new HashSet<DsbRowDataDashboard>(0);

我已经启用了hibernate的所有相关调试来查看sql和debug。这就是导致失败的原因:

[DEBUG] [                                                          org.hibernate.SQL:] [  111] - 
    /* insert com.myapp.model.DsbRowDataDashboard
        */ insert 
        into
            dsb_row_data_dashboard
            (dashboard_id, row_position, row_data_id) 
        values
            (?, ?, ?)
[TRACE] [                              org.hibernate.type.descriptor.sql.BasicBinder:] [   82] - binding parameter [1] as [BIGINT] - 1392
[TRACE] [                              org.hibernate.type.descriptor.sql.BasicBinder:] [   82] - binding parameter [2] as [BIGINT] - 0
[TRACE] [                              org.hibernate.type.descriptor.sql.BasicBinder:] [   82] - binding parameter [3] as [BIGINT] - 50
[TRACE] [                              org.hibernate.type.descriptor.sql.BasicBinder:] [   70] - binding parameter [4] as [BIGINT] - <null>
[DEBUG] [                                         org.hibernate.jdbc.AbstractBatcher:] [  418] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)

之前的sql是插入的父行,它是成功的。然后hibernate尝试插入子进程并失败。整个交易将被回滚。

我设置关系的两边,然后调用hibernate saveorupdate:

   DsbRowDataDashboard rowDataDashboard = new DsbRowDataDashboard(rowData, rowData.getDsbDashboard(), maxpos);
    rowData.getRowPositions().add(rowDataDashboard);
    dsbRowDataDao.update(rowData);

-----

    public T update(T obj) {
        getSessionFactory().getCurrentSession().saveOrUpdate(obj);
        return obj;
    }

我已经看到了另外两个问题几乎完全相同的问题,但没有真正的解决方案。

这是一个非常接近同一问题的问题:

https://stackoverflow.com/questions/37092382/spring-data-jpa-column-index-out-of-range

非常感谢任何见解。

谢谢。

0 个答案:

没有答案