Glassfish - 无法使用 JPA 删除实体

Posted

技术标签:

【中文标题】Glassfish - 无法使用 JPA 删除实体【英文标题】:Glassfish - cannot remove entity using JPA 【发布时间】:2016-03-16 22:50:13 【问题描述】:

在我对 JPA 的探索中,我有下面的代码(我理解不应该在生产中使用)。运行我的代码会产生以下错误:

java.lang.IllegalStateException: 
Exception Description: Cannot use an EntityTransaction while using JTA.

资源代码如下:

@Path("users")
public class UsersAPI 
    @Context
    UriInfo uriInfo;

    @Inject
    UserBean accountsBean;

    @GET
    @Path("deduplicate")
    public Response deduplicateDB()
        List<UserProfile> profiles = accountsBean.getAll();
        int profilesNum = profiles.size();
        for(int i = 0; i < profilesNum; ++i)
            for(int k = 0; k < profilesNum; ++k)
                if(i != k) //if it's not the same profile
                    if(profiles.get(i).getUsername().equals(profiles.get(k).getUsername()))
                        accountsBean.remove(profiles.get(k));
                        profiles.remove(k);
                    
                
                profilesNum = profiles.size();
            
        
        return Response.ok().build();
    

ProfilesBean中的代码如下:

@Local
@Stateless
public class UserBean 
    @PersistenceContext
    EntityManager eManager;

    public void save(UserProfile data)
        eManager.merge(data);
    

    public void remove(UserProfile data)
        eManager.getTransaction().begin();
        eManager.remove(data);
        eManager.getTransaction().commit();
    

    public List<UserProfile> getAll()
        Query q = eManager.createQuery("SELECT profile FROM Users profile");
        return (List<UserProfile>)q.getResultList();
    

这里是实体类的代码:

@Entity(name="Users")
public class UserProfile 
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    Long id;
    String password;
    @Column(unique=true)
    String username;

    public UserProfile(String username)
        setUsername(username);
    
    public UserProfile()
        this(null);
    
    public String getUsername() 
        return username;
    
    public void setUsername(String username) 
        this.username = username;
    

似乎错误来自我以某种方式滥用平台。我怎样才能修复此代码并且以后不会滥用该平台?

【问题讨论】:

【参考方案1】:

如果您在 persistence.xml 文件中使用 JTA 作为事务类型,只需让 JTA 处理您的事务

public void remove(UserProfile data)
    eManager.remove(eManager.merge(data));

更新: 在更清晰的解决方案中,您可以使用“查找”,但您需要提供对象 ID

public void remove(UserProfile data)
    UserProfile e = em.find(UserProfile.class, data.getId());
    eManager.remove(e);

【讨论】:

这可能是一个很好的答案,但什么是 JTA?我不知道在persistence.xml下设置了这样的东西 可能这是您的默认设置。正如规范“在 Java EE 环境中,如果未指定此元素,则默认为 JTA”。在 persistence.xml 中指定是否应该使用 JTA o RESOURCE_LOCAL 来提供数据源。使用 JTA,容器提供数据源。 我会尝试回帖。 我现在收到这个错误:java.lang.IllegalArgumentException: Entity must be managed to call remove: UserProfile 没错,要执行删除操作需要托管实体。试试这个:“eManager.remove(eManager.merge(data));”

以上是关于Glassfish - 无法使用 JPA 删除实体的主要内容,如果未能解决你的问题,请参考以下文章

为什么我的应用程序客户端在GlassFish 4.1.2应用程序上更新JPA实体时会报告StreamCorruptedException?

无法通过持久性删除删除 jpa 子实体

JPA在Kotlin和Glassfish中以双向关系无限递归

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

JEE、eclipselink、glassfish4.0 无法持久化实体

JPA删除实体