当前位置: 首页 > 知识库问答 >
问题:

Hibernate抛出“找到了具有给定标识符的多行”,但之后不会再抛出

白光耀
2023-03-14

我有一个历史表映射到ManyToOne关系视图的应用程序,如下所示

@Entity
@Table(name = "HISTORY_TABLE", schema = "MY_SCHEMA")
public class HAction implements Serializable {
...

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({    
    @JoinColumn(name = "ID_WHO", referencedColumnName = "ID_USER"),
    @JoinColumn(name = "CT_WHO", referencedColumnName = "CT_SEQUENCE")
    })
private VwUsers whoDidTheAction;

...

//Getters & Setters

}

运行应用程序时,遇到了著名的“找到了具有给定标识符的多行”。

因此,我进入调试以找出导致此问题的用户。事实上,它在数据库View对象上有一个副本。但是,在调试过程中,我偶然发现了以下“魔法”

不确定它是否与我的IDE有关,但当在intelliJ(Eclipse上显示)上使用代码检查器并发出以下命令时

hAction.getWhoDidTheAction().getId();

它给了我错误,但当第二次这样做时,在同一个显示“会话”上,没有发生错误,结果如预期的那样。

有人知道这种行为的根源吗?我找不到任何与此相关的东西。

完整的HAction类:

@Entity
@Table(name = "HISTORY_TABLE", schema = "MY_SCHEMA")
public class HAction implements Serializable {

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

 @Id
 @Column(name = "ID_HISTORY_TABLE")
 @SequenceGenerator(name = "SQ_HISTORY_TABLE", sequenceName = "MY_SCHEMA.SQ_HISTORY_TABLE", allocationSize = 1)
 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQ_HISTORY_TABLE")
 private Long idHAction;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_ACTION", referencedColumnName = "ID_ACTION")
 private SAction action;

 @Transient
 private Long idActionTransient;

 @Enumerated(EnumType.STRING)
 @Column(name = "CS_OPERATION")
 private OperationEnum csOperation;

 @Temporal(TemporalType.TIMESTAMP)
 @Column(name = "DT_OPEARATION")
 private Date dhOPeration;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_USER", referencedColumnName = "ID_USER")
 private VwUser user;

 @Column(name = "CD_PROTOCOL")
 private String cdProtocol;

 @Temporal(TemporalType.DATE)
 @Column(name = "DT_PROTOCOL")
 private Date dtProtocol;

 @Column(name = "DS_ACTION")
 private String dsAction;

 @Temporal(TemporalType.DATE)
 @Column(name = "DT_PREDICTION")
 private Date dtPrediction;

 @Enumerated(EnumType.STRING)
 @Column(name = "CS_ORIGIN")
 private OriginEnum csorigin;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_REQUIRED_BY_SECTOR", referencedColumnName = "ID_SECTOR")
 private VwSector vwSector;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_REQUIRED_BY_HQ", referencedColumnName = "ID_HQ")
 private VwHq vwHq;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_REQUIRED_BY_LOCAL", referencedColumnName = "ID_LOCAL")
 private VwLocal vwLocal;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_REQUIRED_BY_ASSOC", referencedColumnName = "ID_ASSOC")
 private VwAssoc vwAssoc;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_REQUIRED_BY_INTER", referencedColumnName = "ID_INTER")
 private VwInter vwInter;

 @Column(name = "DAY_VL")
 private Double dayValue;

 @Column(name = "MAT_VAL")
 private Double matValue;

 @Column(name = "OP_VALUE")
 private Double opValue;

 @Column(name = "TERC_VALUE")
 private Double tercValue;

 @Column(name = "TERC_SERV_VALUE")
 private Double tercServValue;

 @Column(name = "PUB_VALUE")
 private Double pubValue;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_RESPONSIBLE", referencedColumnName = "ID_UNIT")
 private Units unit;

 //This is the first fragment
 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumns({
  @JoinColumn(name = "ID_BOSS", referencedColumnName = "ID_USER"),
  @JoinColumn(name = "CT_BOSS", referencedColumnName = "CT_SEQUENCE")
 })
 private VwUsers whoDidTheActionBoss;
 //
 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumns({
  @JoinColumn(name = "ID_SUB_BOSS", referencedColumnName = "ID_USER"),
  @JoinColumn(name = "CT_SUB_BOSS", referencedColumnName = "CT_SEQUENCE")
 })
 private VwUsers whoDidTheActionSubBoss;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_PHONE", referencedColumnName = "ID_PHONE")
 private VwPhone vwPhone;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_EMAIL", referencedColumnName = "ID_EMAIL")
 private VwEmail vwEmail;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_EMAIL_SUB_BOSS", referencedColumnName = "ID_EMAIL")
 private VwEmail vwEmailSubBoss;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_PHONE_SUB_BOSS", referencedColumnName = "ID_PHONE")
 private vwPhone vwPhoneSubBoss;

 @Column(name = "PROTOCOL")
 private String protocol;

 @Enumerated(EnumType.STRING)
 @Column(name = "CONN")
 private VwConn conn;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "ID_TYPE", referencedColumnName = "ID_TYPE")
 private SType type;

 @OneToMany(fetch = FetchType.LAZY, mappedBy = "id.HAction")
 private List < SFiles > files;

 @OneToMany(fetch = FetchType.LAZY, mappedBy = "id.HAction")
 private List < SThemes > themes;

 @Column(name = "ST_ARCHIVED")
 private Character archived;

 @Temporal(TemporalType.DATE)
 @Column(name = "DT_VIG")
 private Date dtVig;

 /**
  * Create Object {@link HAction}.
  * 
  */
 public HAction() {}

 //Getters & Setters
}

共有1个答案

穆彬郁
2023-03-14

在与一些同事进行了更深入的研究后,我被指出这可能是一种代理实现行为,而且确实如此。

在“getId()”执行期间,代理类检查多对一关系是否满足,如果不满足,它将结果填充为第一个找到的结果的数据,然后抛出异常。这对于调试特别有用,因为它至少为您提供了一个重复对象。这是预期的行为。

由于我在内存中已经有一个对象,因此无需“重新搜索”数据库中的记录,因此“getId()”方法返回第一个元素的id,并且不会引发异常,因为它没有再次查询数据库。

关于代理行为的一些解释可以在这里找到

关于惰性初始值设定项的一些信息可以在这里找到

感谢所有花时间帮助我的人。

 类似资料:
  • 当我尝试使用findById()方法从数据库中获取单个记录时,或者当我尝试使用spring数据REST更新一篇文章时,我遇到了一个异常:找到了具有给定标识符的不止一行。 delete和findAll方法正常工作。 我已经检查了数据库,没有多个相同ID的记录。另外,id是数据库中的唯一键。我见过很多人有同样的错误,但这些人的问题是他们在哪里使用联接。我没有任何加入。 该实体: 存储库: 例外情况:

  • 当我尝试使用findById()方法从数据库中获取单个记录时,或者当我尝试使用spring数据REST更新一篇文章时,我遇到了一个异常:找到了具有给定标识符的不止一行。 delete和findAll方法正常工作。 我已经检查了数据库,没有多个相同ID的记录。另外,id是数据库中的唯一键。我见过很多人有同样的错误,但这些人的问题是他们在哪里使用联接。我没有任何加入。 该实体: 存储库: 例外情况:

  • 在eclipse中调试时 退回申请。isEmpty()?空:应用程序。得到(0); 这些表达式被计算为 applications.is空()- 应用。获取(0)- 应用。大小()- 但在执行这一行之后,它的抛出错误 组织。冬眠HibernateeException:找到了多个具有给定标识符的行:263536, 即使它的大小显示为1,那么它为什么以及如何在执行后获得多行。

  • 我正在开发EJB-JPA-JSF项目。但是我有一个问题。我得到这个查询的错误: 如何修复此错误

  • 我在我的spring boot应用程序中出现了这个错误。当我想调用这个存储库时,我遇到了这个错误 这是我的存储库: 这就是我称之为此方法的地方: 如何检查方法返回的结果?我调试了我的代码,但在断点它只是返回这个错误。 谢谢你的帮助。

  • 我在使用spring数据从1对1关系btn表检索数据时遇到了一个问题。我已经回顾了平台上的几个解决方案,但奇怪的是,在问题首次出现之前,我已经实现了所有建议的解决方案。请帮助我找到我所缺少的东西,或是使对他人有用的解决方案对我无效的任何东西。 以下是这两个实体之间的关系 错误消息: 2021-12-23 15:02:42.116错误11144---[nio-8089-exec-5]o.a.c.c.