为什么这会导致java.sql.SQLIntegrityConstraintViolationException?

时间:2013-11-03 17:06:32

标签: java jpa

我的应用有一个具有此属性和JPA注释的实体类(Ativo):

@JoinColumn(name = "BOLSA", referencedColumnName = "ID")
@ManyToOne(optional = false, cascade = {CascadeType.PERSIST})
private Bolsa bolsa;

当我尝试持久化实体类(Ativo)时,抛出此异常:

内部异常:java.sql.SQLIntegrityConstraintViolationException:语句已中止,因为它会在“BOLSA”中定义的“SQL131102225757700”标识的唯一或主键约束或唯一索引中导致重复键值。< / em>的

我不明白我的代码有什么问题。为什么它会尝试创建一个Bolsa类型的新对象,如果它应该只是现有对象的外键?


Ativo班的标题:

@Entity
@Table(name = "ATIVO")
public class Ativo implements EntityInterface<Ativo>, Serializable {

    private static final long serialVersionUID = 1L;

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

    @Basic(optional = false)
    @Column(name = "CODIGO", unique=true, nullable = false)
    private String codigo;

    @Basic(optional = false)
    @Column(name = "TIPO_MERCADO", nullable = false)
    private String tipoMercado;

    @Column(name = "DESCRICAO", nullable = false, length = 10000)
    private String descricao;

    @JoinColumn(name = "BOLSA", referencedColumnName = "ID")
    @ManyToOne(optional = false, cascade = {CascadeType.PERSIST})
    private Bolsa bolsa;

Bolsa班的标题:

@Entity
@Table(name = "BOLSA")
public class Bolsa implements EntityInterface<Bolsa>, Serializable, Comparable<Bolsa> {

    private static final long serialVersionUID = 1L;

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

    @Basic(optional = false)
    @Column(name = "NOME", unique = true, nullable = false)
    private String nome;

    @Column(name = "DESCRICAO", nullable=false, length = 10000)
    private String descricao;

3 个答案:

答案 0 :(得分:4)

错误消息是显式的:您正在尝试插入数据库中已存在id的行,因此会出现完整性约束违规(重复的主键)。

检查您的代码,即设置id的部分,并确保它使用唯一标识符。或者使用id字段中的注释每次自动生成新密钥。或者定义数据库序列来执行此操作。

答案 1 :(得分:1)

错误消息为您提供了足够的信息来继续挖掘:

a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL131102225757700'

它声明它是主键或唯一键约束,并且给定映射指示的唯一约束(以及我无法看到映射本身有任何错误的事实),我猜它是一个唯一的键约束违例,例如nome字段。但是,错误消息为我们提供了更多内容,这就是被违反的约束的名称:SQL131102225757700。所以,你需要做的是弄清楚这个约束适用于哪个列,一旦你这样做,我猜你会更接近找出错误。 (具体如何做到这一点取决于您的数据库提供商,谷歌...)

答案 2 :(得分:1)

根据评论中的建议,从以下关系中移除cascade = {CascadeType.PERSIST}即可。

@JoinColumn(name = "BOLSA", referencedColumnName = "ID")
@ManyToOne(optional = false, cascade = {CascadeType.PERSIST})
private Bolsa bolsa;

原因是,Cascade Persist负责通过传递持久性将事情放入数据库中,因此您不必明确地保留父项(在您的情况下为'Bolsa')。但是,在持久化之前,始终有责任维护对象的内存状态。

我怀疑(因为从提供的剪辑中不清楚)您在保存Bolsa之前明确保留Ativo对象,因此通过删除级联持久性约束来解决异常。