为外键抛出ConstraintViolationException

时间:2014-08-27 10:30:07

标签: java mysql sql hibernate

当我尝试使用hibernate saveOrUpdate时,我收到了ConstraintViolationException。当我为用户插入一个全新的对象时,保存工作完美但当我尝试更新时失败。

在数据库表中,我有一个唯一的非null主键和一个名为userid

的唯一非空外键

我的pojo声明如下;

@Id @GeneratedValue
@Column(name = "id")
private int id;

@Column(name="userid")
private int userid;

@Column(name = "homephonenumber")
protected String homeContactNumber;

@Column(name = "mobilephonenumber")
protected String mobileContactNumber;

@Column(name = "photo")
private byte[] optionalImage;


@Column(name = "address")
private String address;

我的插入语句如下所示;

public boolean addCardForUser(String userid, Card card) {

    if(StringUtilities.stringEmptyOrNull(userid)){
        throw new IllegalArgumentException("Cannot add card for null or empty user id");
    }

    if(card == null){
        throw new IllegalArgumentException("Cannot null card to the database for user " + userid);
    }

    SessionFactory sf = null;
    Session session = null;

    try{
        sf = HibernateUtil.getSessionFactory();
        session = sf.openSession();
        session.beginTransaction();

        session.saveOrUpdate(card);
        session.getTransaction().commit();
        return true;
    }catch(Exception e){
        logger.error("Unable to add Card to the database for user " + userid );
    }finally{
        DatabaseUtilities.closeSessionFactory(sf);
        DatabaseUtilities.closeSession(session);
    }
    return false;
}

我得到的例外

  

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   密钥'userid_UNIQUE'重复输入'16'

数据库看起来像这样

enter image description here

如果数据库条目没有更新,我做错了什么?

2 个答案:

答案 0 :(得分:0)

您不应对外键设置唯一约束。外键模拟一对多关系船。虽然您的父对象可能只有一个用户,但同一用户可能与多个不同的父对象相关。因此,对于一个userId,父对象表中不一定只有一行。

答案 1 :(得分:0)

对于更新,你应该首先加载Card实例,在更新一些字段之后,然后调用addCardForUser来更新它,如果Card实例没有通过hibernate加载,hibernate将把它作为新记录重新识别,如果这张卡有userId与数据库中的其他卡记录,违反了唯一约束!