如何设置OneToMany关系?

时间:2015-03-07 16:57:00

标签: java-ee jpa ejb

我有点问题。 我有2个实体:用户和图片

图片有外键users_id。 每次我尝试删除有图片的用户时,我都会收到javax.ejb.EJBException:由于此外键,事务已中止。 如何配置我的实体?

实体用户

 @Entity
    @Table(name = "USER1")
    public class User1 implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "ID")
    private Integer id;

    @Size(max = 255)
    @Column(name = "LOGIN", unique=true)
    private String login;

    @Size(max = 255)
    @Column(name = "PASSWORD")
    private String password;

    @Size(max = 255)
    @Pattern(regexp="^[_A-Za-z0-9-]+(\\." +
            "[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*" +
            "(\\.[A-Za-z]{2,})$", message="le mail n'est pas valide")

    @Column(name = "MAIL")
    private String mail;

    @Column(name = "ADMIN")
    private Boolean admin;

    @CascadeOnDelete
    @OneToMany(mappedBy="user", fetch = FetchType.LAZY, orphanRemoval=true, cascade={CascadeType.REMOVE, CascadeType.MERGE})
    private List<Pictures> pictures;

实体图片:

public class Pictures implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Basic(optional = false)
    @NotNull
    @Column(name = "ID")
    private Integer id;

    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "NAME")
    private String name;

    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "PATH")
    private String path;

    @Basic(optional = false)
    @NotNull
    @Column(name = "NB_VIEW")
    private int nbView;

    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "DESCRIPTION")
    private String description;

    @NotNull
    @Lob
    @Column(name="METADATA")
    private String metadata;

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name="user_id")
    private User1 user;

编辑:

我使用DAO删除:

public void remove(T t) {
    getEntityManager().remove(getEntityManager().contains(t)?t:getEntityManager().merge(t));
}

当我删除图片或没有图片的用户时,它的效果非常好。但每当我尝试删除级联用户的照片时,它的工作量就达到百万分之一。

编辑2: 这是用户的控制器

@ManagedBean
@RequestScoped
public class UserController implements Serializable {
    @EJB
    private UserDAO userDAO;
    private static Logger logger = Logger.getLogger(UserController.class);
    private Map<Integer, Boolean> checked = new HashMap<>();

    public List<User1> getAllUsers() {
        return userDAO.findAll();
    }

    public User1 getUserByID(Integer id) {
        return userDAO.find(id);
    }

    public void submit() {
        List<User1> checkedUsers = new ArrayList<>();

        for (User1 user: getAllUsers()) {
            if (checked.get(user.getId())) {
                checkedUsers.add(user);
            }
        }

        checked.clear();

        if (checkedUsers.isEmpty()) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Veuillez sélectionner au moins un utilisateur à supprimer !", null);
            FacesContext.getCurrentInstance().addMessage("form-tabs-1:deleteButton", message);
        }

        for(User1 userToRemove: checkedUsers) {
            removeUser(userToRemove);
        }
    }

    public void removeUser(User1 userToRemove) {
        logger.info("removed user: " + userToRemove.getLogin());
        userDAO.remove(userToRemove);
    }

    public Map<Integer, Boolean> getChecked() {
        return checked;
    }

    public void setChecked(Map<Integer, Boolean> checked) {
        this.checked = checked;
    }
}

2 个答案:

答案 0 :(得分:1)

恕我直言,首先你需要清理你的注释。 并且您需要在用户删除后决定如何处理图片:)

orphanRemoval=trueCascadeType.REMOVE都是多余的,但它们对关系更改有不同的影响。欲了解更多详情: http://www.objectdb.com/java/jpa/persistence/delete

尝试这样的事情:

   //@CascadeOnDelete
   @OneToMany(mappedBy="user",
     fetch = FetchType.LAZY,
     orphanRemoval=true,
     cascade={
     // CascadeType.REMOVE,
        CascadeType.MERGE})
    private List<Pictures> pictures;

此外,您是否可以显示代码块,其中您删除了用户实体? 另外,请尝试删除fetch = FetchType.LAZY注释。

答案 1 :(得分:0)

我相信你的问题是@CascadeOnDelete。删除此注释并再次测试。