在数据库中尝试持久化实体时出现主键问题

时间:2014-05-22 21:18:03

标签: java spring hibernate

在我的spring项目中,使用Hibernate来处理访问数据库的所有操作,我让系统在数据库中创建表,并在其中插入一些默认值。

实体类的一个例子,用作创建表的基础,是:

@Entity
@Table(name="permission")
public class Permissao {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

}

我的问题是,当我尝试在已经插入值的表中通过Java代码插入一行时,我收到一条消息,指出主键已经存在。

我的猜测就是这种情况发生了,因为Hibernate的计数器不会用数据库中的计数器进行更新,但我对这些东西的工作原理还不太了解。

任何人都可以知道发生了什么以及如何解决这个问题?

更新

这就是我在数据库中插入此实体的地方:

public boolean cadastra(HttpServletRequest request, HttpServletResponse response) {
    String nome_grupo = request.getParameter("nome");
    String[] permissoes = request.getParameterValues("permissoes[]");

    if(nome_grupo == null || permissoes == null)
        return false;

    System.out.println("criando grupo");
    GrupoPermissao grupo = new GrupoPermissao();
    grupo.setNome(nome_grupo);

    System.out.println("adicionando permissoes");
    List<Permissao> lista = new ArrayList<Permissao>();
    for(int i=0; i<permissoes.length; i++)
        lista.add(permissao.findById(Integer.valueOf(permissoes[i]).intValue()));
    grupo.setPermissao(lista);

    System.out.println("salvando no banco de dados");
    boolean result = grupo_permissao.persist(grupo);
    System.out.println("id_grupo = "+grupo.getId());
    return result;
}

这是上面使用的实体GrupoPermissao:

@Entity
@Table(name="role")
public class GrupoPermissao {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

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

    @ManyToMany
    @JoinTable(name="role_permissions", joinColumns={@JoinColumn(name="fk_role")}, inverseJoinColumns={@JoinColumn(name="fk_permission")})
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<Permissao> permissao = new ArrayList<Permissao>();

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public List<Permissao> getPermissao() {
        return permissao;
    }

    public void setPermissao(List<Permissao> permissao) {
        this.permissao = permissao;
    }

}

3 个答案:

答案 0 :(得分:0)

您可以在创建对象Permissao时插入id属性。这不是必要的。

答案 1 :(得分:0)

这里的问题可能是您将id声明为原语而不是包装器。

所以而不是:

private int id;

你应该:

private Integer id;

使用以下内容创建群组时:

GrupoPermissao grupo = new GrupoPermissao();

id为0,与NULL不同。

因此,调用此方法的两个请求将尝试将ID设置为0,因此您会发生冲突。

只有当id为NULL时,AUTO生成策略才会让数据库设置id。

Hibernate并没有使用AUTO策略存储任何id计数器,而是将此责任委托给数据库。

答案 2 :(得分:0)

好的,我终于解决了这个问题。问题是用于填充数据库的文件正在使用带有主键指示的INSERT。我删除了这个引用让hibernate处理这个,现在一切正常。