org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行,但它确实存在

我有一个无法修复的hibernate问题。

设置:Java EE,Web应用程序,Hibernate 3.2,Tomcat 6,Struts 2。

基本上,我使用我的服务器逻辑(一个struts动作)持久保存一个对象,然后尝试将该数据拉出来用于下一页并显示它。

我保存对象后检查数据库,果然,我可以在那里查看包含所有数据的行。

但是当我尝试检索它时,我得到了这个:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [msc.model.Picture#73] 

为了使事情变得更加混乱,当我重新启动Tomcat并尝试访问同一个对象时,我没有得到错误 – Hibernate发现行就好了。

如果我做一些其他的操作,Hibernate也能看到该行 – 也许在这里和那里添加一行到数据库,甚至不在同一个表上。

从这一切我怀疑一个Hibernate错误,但我是一个Hibernate新手,所以我可能错了。 请帮忙! 我用Google搜索并用Google搜索无效。

这是我的Hibernate配置:

     org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/msc root -------  80 thread  true     

这是我的两个映射文件:

                               

                    

如果您需要更多信息,请告诉我,我很高兴。

(注意:这不是这个问题的重复,场景不一样“没有给定标识符的行存在”,尽管它存在 )

编辑 :根据要求,发布Java代码:

用于保存对象的代码

 Session hib_ses = HibernateUtil.getSessionFactory().getCurrentSession(); hib_ses.beginTransaction(); hib_ses.save(user); hib_ses.getTransaction().commit(); 

显示数据的代码(本例中为图像)

 public class ImageAction extends ActionSupport implements ServletResponseAware, SessionAware { private HttpServletResponse response; Map session; private Long id; private int thumbnail; private InputStream inputStream; @Override public String execute() throws Exception { response.setContentType("image/jpeg"); Session hib_session = HibernateUtil.getSessionFactory().getCurrentSession(); hib_session.beginTransaction(); //what is the ID now? Picture pic = (Picture) hib_session.load(Picture.class, getId()); if (thumbnail == 1) { inputStream = (ByteArrayInputStream) pic.getThumbnail().getBinaryStream(); } else { inputStream = (ByteArrayInputStream) pic.getRefinedImage().getBinaryStream(); } hib_session.close(); return SUCCESS; } 

检查所有映射和数据库设置。 当您的数据库显示nullable =“true”时,您可能在外键关系中设置了一些not-null =“true”。 第一个导致INNER JOIN,第二个导致LEFT JOIN。

将日志级别设置为TRACE以查看所有步骤,并在检索对象时查找生成的SQL。

发生这种情况是因为您插入了一些外键,但没有引用任何内容。 检查数据库是否存在该密钥(即使它在其他表的数据库中)。

只需检查您的数据库是否在您的特定表中可用ID 73

好的,我要在这里抛出一个理论。 可能是您在提交事务之前第一次尝试加载图片吗?

由于事务尚未提交,因此您用于读取图片的事务对该行不可见(取决于您具有的事务隔离级别)。

然后,由于hib_session.close()不在finally块内,因此不会执行,并且线程绑定会话仍将具有打开的事务。 后续请求获得相同的 Hibernate会话,具有相同的打开事务,并且您从select it问题中获得相同的结果(再次,取决于事务隔离级别 – 请参阅此处的文档 ,特别是REPEATABLE_READ)。

这也可以解释为什么flush()使它稍好一些,因为如果flush()发生在commit() ,则竞争条件发生的可能性较小。

我建议你尝试在finally块中关闭会话,看看后续请求的行为是否发生了变化。

在多对一关系中,您需要告诉Hibernate如果找不到映射的行,需要做什么。 您可以通过以下方式配置它:

 Annotation: @NotFound(action = NotFoundAction.IGNORE) Mapping XML:  

我没有看到任何与代码中的exception有关的实际问题,您可能想尝试:

  • 检查事务是否已刷新或在提交后手动调用flush() ;
  • 检查ID是否传递给load()以及是否通过调试器将正确的ID传递给它
  • 启用Hibernate以打印生成的SQL和/或启用日志记录

我有一个与hibernate 3.6.10类似的问题,而我只是搜索和选择(如果存在)。

注解:

 @Entity public class Familiares { @OneToMany(mappedBy = "familiares") private List bajas; @Entity @Table(name = "familiares_baja") public class FamiliaresBaja implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @JoinColumn(name = "familiares_id") @ManyToOne(optional = false) private Familiares familiares; 

然后我检索一个列表,如果有至少一个,看看FamiliaresBaja。

 createQuery("from FamiliaresBaja where familiares.id="+ id).uniqueResult() // should return a single result or null not throw a Exception 

这必须是一个Hibernate错误

请检查mysql服务器的lower_case_table_names的值。 如果其值为0,请检查hibernate生成的SQL,确保表名的大小写与mysql中的实际表名一致。

我面对这个问题,这里发生了什么以及我如何解决它。 你很可能也有同样的事情发生。

我有POST和USER对象。 他们处于OneToMany关系中(用户可以有很多post)。 使它成为双向的,它们也处于ManyToOne关系中(一个post只属于一个用户)。

邮政课看起来

 @Entity @Table(name="Post") public class Post { @Id @GeneratedValue(strategy=GenerationType.TABLE) private long postId; private String title; private String body; @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name = "postUserId") private AutoUser autoUser; // getter and setters 

用户类是

 @Entity @Table(name = "AUTO_USER") public class AutoUser implements UserDetails { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long autoUserId; @Column(name = "USERNAME") private String username; @OneToMany private List postList = new ArrayList<>(); // getter and setters 

第一个表名是Post和AUTO_USER我有3个用户持久化到AUTO_USER表(id为1,2,3)..并为每个用户输入3个Post表1。 (连接列或外键为1,2,3)

然后我只更改了用户对象的表名,并将其命名为@Table(name = "AUTO_USER2") 。 我在这个表中只有一个id为1的用户。

在我的代码中,我遍历每个post并确定哪个post属于哪个用户,并显示属于当前登录用户的post。

更改post表名后,我得到了这个例外

 org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tadtab.core.authentication.AutoUser#2 

这告诉我,ID为2的用户对象在新用户表中不可用。

然后我注册了另一个id为2的用户,后来我得到了这个

 org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tadtab.core.authentication.AutoUser#3 

这次它找不到ID为3的用户

最后注册了第三个用户,并没有例外。

正如您所看到的,外键存在于post表中,但由于我更改了用户表,因此无法匹配它们,这就是我遇到此问题的原因。

为了避免这种情况,我为两个对象创建了新的表名并重新开始

希望这会有所帮助