【问题标题】:Hibernate: Parameter index out of range (8 > number of parameters, which is 7)Hibernate:参数索引超出范围(8>参数个数,即7)
【发布时间】:2015-03-25 03:01:55
【问题描述】:

不是这个问题的重复Parameter index out of range (8 > number of parameters, which is 7)

我的 SaltTranDef 实体类是

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

@Column(name="tran_type")
private String transactionType;

@Column(name="user_id")
private String userId;

@Column(name="parent_system")
private String parentSystem;

@Column(name="parent_sys_ref_id")
private String parentSystemReference;

@Column(name="status")
private int status;

@OneToMany(mappedBy = "saltTranDef")
@Cascade({ org.hibernate.annotations.CascadeType.ALL,
         org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private Set<SaltTranUser> saltTranUsers;

而 SaltTranUser 实体类是

@Id
@Column(name="salt_id")
private Integer saltId;

@Id
@Column(name="salt_property")
private String saltProp;

@Column(name="salt_value")
private String saltValue;

@ManyToOne
@JoinColumn(name="salt_id")
private SaltTranDef saltTranDef;

以上两个实体类都扩展了一个mappedSuperclass

@Column(name="cre_suid")
private String creatorId;

@Column(name="mod_suid")
private String modifiedId;

@Column(name="cre_date")
private Timestamp creationDate;

@Column(name="mod_date")
private Timestamp modificationDate;

从 JUnit 插入时:

@Test
public void testInsert(){

    SaltTranDef std = new SaltTranDef();
    SaltTranUser stu1 = new SaltTranUser();
    SaltTranUser stu2 = new SaltTranUser();
    SaltTranUser stu3 = new SaltTranUser();
    Set<SaltTranUser> set1 = new HashSet<SaltTranUser>();

    Transaction tx = session.beginTransaction();

    std.setParentSystem("A");
    std.setParentSystemReference("123");
    std.setStatus(10);
    std.setTransactionType("A");
    std.setUserId("1234");
    std.setCreationDate(new Timestamp(new Date().getTime()));
    std.setCreatorId("1234");

    session.persist(std);
//  session.flush();

    stu1.setCreationDate(new Timestamp(new Date().getTime()));
    stu1.setCreatorId("1234");
    stu1.setSaltProp("Fname");
    stu1.setSaltValue("Swateek");
    stu1.setSaltId(std.getSaltId());

    stu2.setCreationDate(new Timestamp(new Date().getTime()));
    stu2.setCreatorId("1234");
    stu2.setSaltProp("Lname");
    stu2.setSaltValue("Jena");
    stu2.setSaltId(std.getSaltId());

    stu3.setCreationDate(new Timestamp(new Date().getTime()));
    stu3.setCreatorId("1234");
    stu3.setSaltProp("Phone");
    stu3.setSaltValue("9900056668");
    stu3.setSaltId(std.getSaltId());

    set1.add(stu1);
    set1.add(stu2);
    set1.add(stu3);

    std.setSaltTranUsers(set1);

    session.save(std);
    tx.commit();
}

我收到一条错误消息:

SEVERE:参数索引超出范围(8 > 参数个数,即 7)。 2015 年 3 月 25 日上午 8:06:35 org.hibernate.event.def.AbstractFlushingEventListener performExecutions 严重:无法将数据库状态与会话同步 org.hibernate.exception.GenericJDBCException:无法插入:[com.salt.entity.SaltTranUser] 在 org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103) 原因:java.sql.SQLException: Parameter index out of range (8 > number of parameters, which is 7)。 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)

【问题讨论】:

  • @Transient 放在@ManyToOne 之前对我来说效果很好。

标签: java hibernate


【解决方案1】:

这类问题几乎总是与双列映射有关。确实如此。我们可以看到,这个映射使用一列两次 "salt_id"

SaltTranUser 实体类:

@Id
@Column(name="salt_id")
private Integer saltId;
...

@ManyToOne
@JoinColumn(name="salt_id")
private SaltTranDef saltTranDef;

这是错误的。 Hibernate 最后两次插入一列,即更多参数然后是 INSERT、UPDATE 中的列

这里的解决方案很可能非常简单 - 因为@ManyToOne 似乎是错误的。我希望有一些特别的专栏可供参考,例如:SaltTranDef_id

【讨论】:

  • 这种方法由于某些业务原因我无法解决。因此,在第二个表中,第一个表的 Identity 列和另一列将是复合主键。第二个表中的标识列将是依赖于第一个表的外键。
  • 将其标记为只读。但总的来说,我的答案是答案。一列的两个映射不能用作可写...希望对您有所帮助
  • 现在..在实体类中进行了一些更改..(我也只读过)这个错误不会出现。但是还有其他事情要发生,我很困惑是否应该编辑这个问题或开始一个不同的线程?请帮忙。
  • 要获得更多关注,请提出新问题。这在堆栈中。
  • 这是我发布的新问题,实体类也有一些变化。如果你能请帮忙。 stackoverflow.com/questions/29285225/…
【解决方案2】:

我在使用单向映射时遇到了同样的问题(父类包含子类,但子类不保留父类的引用)。 映射看起来像

@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name="jobcard_id", nullable=false)
private List<JobServiceMapping> services;

我收到错误参数索引超出范围。 然后我稍微更改了注释,现在它对我有用。

@OneToMany(mappedBy="jobcardId", cascade = CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval = true)
private List<JobServiceMapping> services;

【讨论】:

    【解决方案3】:

    在我的情况下,问题是 user_type 字段。它被定义为歧视者和公共财产。它没有用@Column 标记,但不知何故,Hibernate 无论如何都失败了

    @Entity
    @Table(
        name = "abstract_users",
        indexes = {@Index(name = "idx__abstract_users__is_enabled", columnList = "is_enabled")}
    )
    @Access(AccessType.FIELD)
    @Inheritance(strategy = InheritanceType.JOINED)
    // @TODO: rename user_type to discriminator
    @DiscriminatorColumn(name = "user_type", discriminatorType = DiscriminatorType.STRING, length = 10)
    abstract public class AbstractUser extends CreateUpdateTimestampableBase
    {
    
        // @TODO: rename user_type to discriminator
        public String user_type;
    
        @Min(0)
        @NotNull
        @Column(precision = 19, scale = 2)
        protected BigDecimal balance;
    
        //...
    }
    

    【讨论】:

    • Hibernate 会拾取任何未标记为瞬态或未使用 @Transient 注释的属性。这就是为什么将 user_type 检测为数据库列的原因。
    • 我们可以说Hibernate不允许你使用鉴别器列作为类的属性吗?
    • 帮助我,谢谢
    【解决方案4】:

    在您的实体中,替换

    @ManyToOne
    @JoinColumn(name="salt_id")
    private SaltTranDef saltTranDef;
    

    通过

    @ManyToOne
    @JoinColumn(name="salt_id", updatable = false, insertable = false)
    private SaltTranDef saltTranDef;
    

    对我有用

    【讨论】:

      猜你喜欢
      • 2013-07-22
      • 2022-01-04
      • 2020-02-21
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 2014-03-29
      • 1970-01-01
      相关资源
      最近更新 更多