【问题标题】:Duplicate entry error occurs on saveorupdate methodsaveorupdate方法出现重复输入错误
【发布时间】:2014-12-06 07:39:29
【问题描述】:

我尝试在休眠中使用 saveorupdate 方法,结果是

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Mobiles' for key 'type_name'

这是我的代码

public ItemType addItemType(String typeName) {
    Session session = factory.openSession();

    Transaction tx = null;
    ItemType itemType = null;
    try{
        tx = session.beginTransaction();
        itemType = new ItemType();
        itemType.setTypeName(typeName);
        itemType.setDescription("");
        itemType.setCreatedBy("shoppingcart");
        itemType.setCreatedDate(new Date());
        itemType.setUpdatedBy("shoppingcart");
        itemType.setUpdatedDate(new Date());
        session.saveOrUpdate(itemType); 
        tx.commit();
    }catch (HibernateException e) {
        if (tx!=null) tx.rollback();
        e.printStackTrace(); 
    }finally {
        session.close(); 
    }
    return itemType;
}

这是 ItemType 类

@Entity
@Table(name = "item_types")
public class ItemType implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_type_id")
private String typeId;

@Column(name = "type_name")
private String typeName;

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

@Column(name = "created_date")
private Date createdDate;
@Column(name = "created_user")
private String createdBy;
@Column(name = "updated_date")
private Date updatedDate;
@Column(name = "updated_user")
private String updatedBy;

public String getTypeName() {
    return typeName;
}

public void setTypeName(String typeName) {
    this.typeName = typeName;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getTypeId() {
    return typeId;
}

public void setTypeId(String typeId) {
    this.typeId = typeId;
}

public Date getCreatedDate() {
    return createdDate;
}

public void setCreatedDate(Date createdDate) {
    this.createdDate = createdDate;
}

public String getCreatedBy() {
    return createdBy;
}

public void setCreatedBy(String createdBy) {
    this.createdBy = createdBy;
}

public Date getUpdatedDate() {
    return updatedDate;
}

public void setUpdatedDate(Date updatedDate) {
    this.updatedDate = updatedDate;
}

public String getUpdatedBy() {
    return updatedBy;
}

public void setUpdatedBy(String updatedBy) {
    this.updatedBy = updatedBy;
}   


}

首先我做了一个插入条目,它工作正常,当我尝试更新时,我猜它会尝试进行插入并导致上述错误。请帮忙。

更新

这是db中的表结构

DROP TABLE IF EXISTS `shopping_cart`.`item_types`;
CREATE TABLE  `shopping_cart`.`item_types` (
`item_type_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`type_name` varchar(45) NOT NULL,
`description` varchar(450) DEFAULT NULL,
`created_user` varchar(45) NOT NULL,
`created_date` datetime NOT NULL,
`updated_user` varchar(45) NOT NULL,
`updated_date` datetime NOT NULL,
PRIMARY KEY (`item_type_id`),
UNIQUE KEY `type_name` (`type_name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

【问题讨论】:

    标签: java database hibernate jpa orm


    【解决方案1】:

    您的代码总是保存一个新的 ItemType,并且由于您的数据库对“type_name”有一个唯一约束,您在第二次尝试运行此方法时会遇到该异常(对于相同的 type_name) .

    所以,你不能使用 hbmddl,否则你的 Hibernate ItemType 模型必须使用:

    @Column(name = "type_name", unique = "true")
    private String typeName;
    

    您需要在保存之前按 typeName 选择 ItemType:

    public ItemType addItemType(String typeName) {
        Session session = factory.openSession();
    
        Transaction tx = null;
        ItemType itemType = null;
        try{
            tx = session.beginTransaction();
            itemType = session.createQuery("select it from ItemType where typeName = :typeName")
                       .setParameter("typeName", typeName)
                       .uniqueResult();
            if(itemType == null) {
                itemType = new ItemType();
                itemType.setTypeName(typeName);
                itemType.setDescription("");
                itemType.setCreatedBy("shoppingcart")    
                itemType.setCreatedDate(new Date());
            }
            itemType.setUpdatedBy("shoppingcart");
            itemType.setUpdatedDate(new Date());
            session.saveOrUpdate(itemType); 
            tx.commit();
        }catch (HibernateException e) {
            if (tx!=null) tx.rollback();
                e.printStackTrace(); 
        }finally {
            session.close(); 
        }
        return itemType;
    }
    

    【讨论】:

    • 是 Type_Name 具有唯一约束。我已更新问题以包含数据库结构。让我试试你的解决方案。
    • gr8 您的解决方案有效。我猜在“从 ItemType 中选择它”中,“它”是别名。我已将查询更新为“从 ItemType 中选择它”,它运行良好 :)
    【解决方案2】:

    如果您只是运行相同的代码,尝试更新实体而不是保存它,它将失败。要使用此方法更新实体,您不能创建 new ItemType,而是使用 session.get(ItemType.class, id); 从 db 获取它 - 这样 hibernate 会理解,该实体已经在 db 中,并尝试更新它,而不是保存一个新的

    【讨论】:

    • 我正在动态生成 id。我现在如何获取 id?
    • 提交后,你应该在你的类中的 typeId 字段填充了 id。
    • 哦,我明白了,在第一次运行时我需要设置 id,然后我需要在第二次运行时使用它对吗?
    猜你喜欢
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多