我有一个名为ad_session
的表,用于记录用户会话。(这是ad_user
表的外键)。然后,我获取属于该用户的客户机,并将该客户机添加到列表中。但是,其中一个用户已不存在,所以我的代码停止运行,并抛出以下异常:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [ADUser#76A5C22E6D2446A399AE9AD7C1DED0C7]
这是我的原始代码:
List<Session> sessions = getAllSuccessfulSessionsInTable();
List<Client> clientsForThatDay = new ArrayList<>();
try {
for (Session session : sessions) {
//code fails when trying to get the non-existent user:
User user = session.getCreatedBy();
Client userClient = user.getClient();
clientsForThatDay.add(userClient);
}
} catch (Exception e) {
log.error("Error getting client from user: ", e);
}
我假设当获取一个不存在的记录时,它会返回null,所以我尝试了以下方法:
List<Session> sessions = getAllSuccessfulSessionsInTable();
List<Client> clientsForThatDay = new ArrayList<>();
//Create new user object to stand in place of the non-existent user
User deletedUser = new User();
deletedUser.setName("Deleted User");
//Create new client object to stand in place of the non-existent client
Client deletedUserClient = new Client();
deletedUserClient.setName("Unknown Client");
try {
for (Session session : sessions) {
//check is User is null, if it is, use the deletedUser object, otherwise, use the existing user
User user = session.getCreatedBy() == null ? deletedUser : session.getCreatedBy();
Client userClient = user.getName().equals("Deleted User") ? deletedUserClient : user.getClient();
clientsForThatDay.add(userClient);
}
} catch (Exception e) {
log.error("Error getting client from user: ", e);
}
但是,它并没有返回null,它只是抛出异常,然后停止。**我如何才能让它在这里返回null,这样我就可以在不停止代码的情况下处理丢失的记录?**提前感谢您的建议。
1条答案
按热度按时间oxalkeyp1#
您的数据库似乎缺少外键约束。这意味着表Map
User
引用了Client
表中不再存在的行。只有在删除了客户端而没有更新用户表的情况下才会发生这种情况。解决方法是在表之间添加外键约束。
请记住,如果表中的数据不正确,当Hibernate加载实体
User
时,它也会认为存在一个客户端。这意味着User#getClient
不会为空,代码中的每个地方都将出现类似user.getClient() == null
的检查。try-catch方法在这方面没有帮助(我猜,除非在出错的情况下将关联设置为null)。我能想到的解决方案:
1.添加外键约束(imho,最佳解决方案)
1.不要Map关联,将
client_id
Map为属性,然后使用第二个查询或find加载客户端(只有在无法更新数据库时,我才会这样做)1.您可以通过
session.find(Client.class, user.getClient().getId())
加载客户端并设置与结果的关联:1.根本不要在
User
中Map关联,并运行本机SQL查询来加载客户端:您可以选择最适合您的方法,但请记住,Map没有外键约束的关联将导致各种一致性问题。
我之所以选择选项3,只是因为有时候人们在工作中会遇到一些不可能的情况,但我不会推荐它。