在我的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;
}
}
答案 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处理这个,现在一切正常。