代码之家  ›  专栏  ›  技术社区  ›  cdmckay

EntityManager.Find找不到实体,但使用条件API可以

  •  7
  • cdmckay  · 技术社区  · 14 年前

    我在JavaEE 6中遇到了一个非常奇怪的例子,在这里使用JPA实体管理器 find 方法和实体的主ID一起返回空值,但使用条件API选择具有该ID的所有实体可以正常工作。

    这是我用的代码 找到 :

    // Always returns null, even for records I know for sure are in there.
    user = em.find(User.class, userId);
    

    …下面是我在标准API中使用的代码:

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<User> criteria = builder.createQuery(User.class);
    Root<User> u = criteria.from(User.class);
    TypedQuery<User> query = em.createQuery(
        criteria.select(u).where(builder.equal(u.get("id"), userId)));
    user = query.getSingleResult();
    

    知道为什么 找到 返回空值,但条件查找用户?我在程序中的同一个地方尝试了这两种替代方法。

    以下是用户实体的相关部分:

    @Entity
    @Table(name = "USERS")
    @Access(AccessType.PROPERTY)
    public class User implements Serializable {
        ...
        private Long id;
        ...
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_generator")
        @SequenceGenerator(name = "user_id_generator", sequenceName = "user_sequence", allocationSize = 1)
        @Column(name="id")
        public Long getId() {
            return this.id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
        ...
    }
    
    6 回复  |  直到 8 年前
        1
  •  11
  •   cdmckay    14 年前

    我解决了问题。这是由于数据库中的一个字段 null 在不应该被允许的地方。这是由于我手工编辑的缘故。在我为该字段添加值之后,问题就消失了。

        2
  •  3
  •   Peter Krogh    14 年前

    您使用的是什么提供商?

    在事务中或事务外,您在哪里执行此查找?你是在发现之前冲洗和清除电磁波吗?

    使用EclipseLink作为提供者,以及我自己的类似模型,我无法复制这个模型。

    假设您的提供程序可以记录SQL,您是否看到SQL将在查找时转到数据库?SQL是什么样子的,它在SQL Plus等中是否正确执行…

        3
  •  3
  •   Javasick Kumar Vivek Mitra    8 年前

    我确认解决方案。同样的事情也发生在我身上。我把柱标为 NOT NULL ,然后在应用程序测试期间,我关闭了数据库中两列(外键)的限制,但没有更改( optional = false 属性 @ManyToOne 我的实体类中的关系。删除属性后,模型与数据库保持一致,一切都开始正常工作。 奇怪的是,环境并没有产生某种警告或异常。

        4
  •  1
  •   Pascal Thivent    14 年前

    再次确认您通过了 Long 在以下代码段中:

    // Always returns null, even for records I know for sure are in there.
    user = em.find(User.class, userId);
    

    如果这不起作用,请激活SQL日志记录以查看正在发生的情况,并比较这两种情况下的行为。

        5
  •  0
  •   bashflyng    14 年前

    一个原因可能是“id”字段没有正确标记为用户实体的id。

        6
  •  0
  •   apiri    14 年前

    作为一个健全性检查,调试您的代码,在执行find之前花些时间自己对数据库运行手动查询,以确保使用您期望的ID提供适当的用户记录。

    如果它不在数据库中,请确保已刷新实体管理器或已提交当前事务。

    例如,如果您使用Hibernate作为提供程序,则可能对象仅在缓存中被“持久化”,并且更改实际上没有被推送到数据库中。因此,通过Hibernate实现的条件将检索对象,但实体管理器查找将无法定位对象。