【问题标题】:Glassfish - cannot remove entity using JPAGlassfish - 无法使用 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;
    }
}

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

【问题讨论】:

    标签: jax-rs jpa-2.1 glassfish-4.1 jakarta-ee


    【解决方案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));”
    猜你喜欢
    • 2015-11-07
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    相关资源
    最近更新 更多