【问题标题】:Can't remove entity with JPA无法使用 JPA 删除实体
【发布时间】:2015-11-07 10:31:35
【问题描述】:

我正在尝试使用 JPA 从内存中删除一个实体(目前我不使用 DB),当我使用 remove 然后尝试找到它显示为 null 的已删除实体时,但是当我使用findAll 方法检索所有数据(删除实体)...

Profile.java

@Entity
@Table(name = "profile")
public class Profile {

    @Id
    @GeneratedValue
    private Long id;

    private String nombre;

    private Boolean restrictedAccess;

    private Boolean canValidate;

    // private Set<AccessField> accessFields = new HashSet<AccessField>();

    // private Set<AccessEntity> accessEntities = new HashSet<AccessEntity>();
    @OneToMany(mappedBy = "profile", fetch = FetchType.EAGER)
    private Set<AccessMenu> menuSections = new HashSet<AccessMenu>();

    @OneToMany(mappedBy = "profile", fetch = FetchType.EAGER)
    private Set<User> users = new HashSet<User>();
[getters and setters]

个人资料库

@Repository
@Transactional
public class ProfileRepository {
    @PersistenceContext
    private EntityManager entityManager;

    public Profile save(Profile p) {
        p = this.entityManager.merge(p);
        this.entityManager.flush();
        return p;
    }

    public void delete(Long id){
        Profile profile = this.entityManager.find(Profile.class, id);
        this.entityManager.remove(profile);
    }

    public List<Profile> findAll() {
        CriteriaQuery cq = this.entityManager.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Profile.class));
        return (List<Profile>) this.entityManager.createQuery(cq).getResultList();
    }

    public Profile findById(Long id){
        return this.entityManager.find(Profile.class, id);
    }
}

控制器方法

@RequestMapping(value="profile/delete/{idProfile}", method = RequestMethod.GET)
    public String delete(@PathVariable String idProfile,RedirectAttributes ra, Model model){


        profileRepo.delete(Long.valueOf(idProfile));

        model.addAttribute("profiles", profileRepo.findAll());

        return "profile/list";
    }

【问题讨论】:

  • 为什么叫 Profile "delProfile = this.entityManager.merge(profile);"再次在删除功能中?
  • 因为我在某处读到我必须调用合并来获得相同的事务
  • 顺便说一句,即使 deleteById 是我在回答中给出的示例中的正确方法,如果您仍然不想更改代码,问题是在删除您的同时还通过调用“Profile delProfile = this.entityManager.merge(profile);”来保存另一个实体并同时删除您新创建的实体。因此,您的实际实体不会被删除。
  • 尝试删除@Transactional(readOnly = true) 并单独使用@Transaction 进行注释?你试过了吗?
  • 现在我把@Transactional 单独放了,没有用。我将编辑主要问题

标签: java spring-mvc jpa


【解决方案1】:

如果您试图通过在控制器中使用 Id 来删除实体,请像 profileRepo.deleteById(Long.valueOf(idProfile)); 这个,不像这个profileRepo.delete(profileRepo.findById(Long.valueOf(idProfile)));

也可以像这样使用您的存储库功能,

public void deleteArtistById(Long artistId) {
    Artist artist = manager.find(Artist.class, artistId);
    if (artist != null) {
        manager.getTransaction().begin();
        manager.remove(artist);
        manager.getTransaction().commit();
    }
}


public void deleteArtist(Artist artist) {
    manager.getTransaction().begin();
    manager.remove(artist);
    manager.getTransaction().commit();
}

您可以查看此链接以获取更多详细信息: http://kodejava.org/how-do-i-delete-entity-object-in-jpa/

【讨论】:

  • 我想我不能将 .getTransaction.begin() 与 @Transactional 注释一起使用,它会抛出此错误 java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead 但感谢您的建议,我将使用新方法编辑问题
  • 如果您使用@Transactional 注释,您可以不使用getTransaction() 方法删除并重试。这是我分享的链接的复制粘贴,因此您需要对其进行更改以使其与您的代码一起使用。
  • 我做到了但不起作用,当我使用 findAll() 时它会找到已删除的注册表
【解决方案2】:

最后我找到了解决方案,问题是当我试图删除ProfileusersmenuSections有相关数据,所以最后我把menuSections一个cascade = CascadeType.REMOVEusersprofile 属性设置为null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多