我有一个历史表映射到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
}
在与一些同事进行了更深入的研究后,我被指出这可能是一种代理实现行为,而且确实如此。
在“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.