相关疑难解决方法(0)

从JPA/EJB3持久性上下文中分离实体

分离通过EntityManager获取的特定JPA实体Bean的最简单方法是什么?或者,我可以让查询首先返回分离的对象,这样它们基本上可以作为"只读"吗?

我想这样做的原因是因为我想修改bean中的数据 - 仅在我的应用程序中,但不会将其持久保存到数据库中.在我的程序中,我最终必须在EntityManager上调用flush(),它会将所有更改从附加实体持久保存到underyling数据库,但我想排除特定对象.

java orm jpa

54
推荐指数
4
解决办法
7万
查看次数

如何在后端数据库异步更改时刷新JPA实体?

我有一个PostgreSQL 8.4数据库,其中包含一些表和视图,这些表和视图基本上是连接在某些表上的.我使用的NetBeans 7.2(如描述这里)来从这些观点和表中派生的基于REST的服务,并部署那些到Glassfish的3.1.2.2服务器.

还有另一个进程异步更新用于构建视图的一些表中的内容.我可以直接查询视图和表格,看看这些变化是否正确发生.但是,从基于REST的服务中提取时,这些值与数据库中的值不同.我假设这是因为JPA已经缓存了Glassfish服务器上的数据库内容的本地副本,JPA需要刷新关联的实体.

我尝试将一些方法添加到NetBeans生成的AbstractFacade类中:

public abstract class AbstractFacade<T> {
    private Class<T> entityClass;
    private String entityName;
    private static boolean _refresh = true;

    public static void refresh() { _refresh = true; }

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
        this.entityName = entityClass.getSimpleName();
    }

    private void doRefresh() {
        if (_refresh) {
            EntityManager em = getEntityManager();
            em.flush();

            for (EntityType<?> entity : em.getMetamodel().getEntities()) {
                if (entity.getName().contains(entityName)) {
                    try {
                        em.refresh(entity);
                        // log success
                    }
                    catch (IllegalArgumentException e) {
                        // log failure ... …
Run Code Online (Sandbox Code Playgroud)

java postgresql netbeans jpa glassfish

35
推荐指数
2
解决办法
9万
查看次数

使用 JPA 时避免来自 DB 的陈旧数据?

我面临一个类似于Invalidating JPA EntityManager session 中描述的问题:

问题:获取陈旧数据

我们正在 SQL 数据库上运行 JPQL 查询,该数据库也由不同的应用程序同时更改。我们使用的是在Tomcat下运行的JSF+Spring+EclipseLink。

执行 JPQL 查询的类是一个单例 Spring bean,并使用注入的EntityManager

@Component
public class DataRepository{
    @PersistenceContext
    private EntityManager entityManager;
    public List<MyDTO> getStuff(long id) {
        String jpqlQuery ="SELECT new MyDTO([...])";
        TypedQuery<MyDTO> query = entityManager.createQuery(jpqlQuery,MyDTO.class);
        return query.getResultList();
    }
[...]
Run Code Online (Sandbox Code Playgroud)

(代码释义)。

问题是这段代码看不到直接对数据库执行的更改。这些更改仅在 Tomcat 实例重新启动时才可见。

我们尝试过的

我们假设此行为是由与 关联的一级缓存引起的EntityManager,如链接问题中所述。我们找到了两个解决方案:

  • 调用entityManager.clear()调用之前createQuery(这是建议的链接的问题)
  • 注入一个EntityManagerFactor(使用@PersistenceUnit),然后EntityManager为每个查询创建并关闭一个新的

两种解决方案都能满足我们的需求——我们获得了新的数据。

问题:

  • 这两种解决方案是否正确?哪一个更好?
  • 特别是,我们是否可以安全地调用entityManager.clear()注入的 EntityManager,或者这是否会以某种方式影响也使用注入的 EntityManager 的其他代码(在相同或不同的类中)?
  • 有没有不同的、更好的方法?我们能不能以某种方式声明我们想要刷新缓存,或者我们想要一个新的EntityManager

我认为这一定是一个相当普遍的问题(因为它发生在多个应用程序共享一个数据库时),所以我认为必须有一个简单的解决方案......

database spring caching jpa eclipselink

5
推荐指数
2
解决办法
6637
查看次数

获取集合时 JPA Lazy Fetch 不起作用

我正在获取对象的集合,并尝试在 @ManyToOne 关系中使用延迟加载来获取对象。但是,当我调用服务方法时,集合中的对象获得 NULL 值

List<Location> all = locationRepository.getLocations(ids);
Merchant merchant = all.get(0).getMerchant();
// merchant == null
Run Code Online (Sandbox Code Playgroud)

LocationRepository.java

@Repository
public interface LocationRepository extends JpaRepository<Location, String> {

    @Query(value = "SELECT * FROM b_location WHERE id IN :ids", nativeQuery = true)
    List<Location> getLocations(@Param("ids") Set<String> ids);
    }
Run Code Online (Sandbox Code Playgroud)

位置.java

@Entity
@Table(name = "b_location")
public class Location {

    @Id
    @Column(name = "id")
    private String id;

    @Column(name = "merchant_id", nullable = false)
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private Long merchantId;

    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "merchant_id", referencedColumnName = "id", …
Run Code Online (Sandbox Code Playgroud)

java hibernate jpa spring-data-jpa spring-boot

1
推荐指数
1
解决办法
2605
查看次数