我正在使用arquillian进行容器内测试。我通过向部署添加import.sql
来预填充数据库。在测试期间,我想创建更多实体。
不幸的是,这失败了PersistenceException
:
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException:唯一索引或 主键冲突:“PRIMARY_KEY_BE ON PUBLIC.KVS_MIPO_DOWNLOAD(ID)“
如果我没有预先填充数据库,或者没有保留新实体,那么一切都会顺利进行。
id是唯一的唯一字段,所以我强烈怀疑它必须是使用序列的id生成。
@Entity
@Table(name = "KVS_MIPO_DOWNLOAD")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class DownloadResource implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Integer id;
此实体是另一个具体实体的超类,它不会添加任何唯一属性。
可以做些什么来容纳两种可能性 - 手动插入和使用生成的ID?
谢谢
我在JBoss 7.1.1中使用JPA 2而不是Hibernate 4.0.1。该数据库是Sybase ASE 15。
编辑:到目前为止我找到的一个解决方法是将手动添加的实体的ID设置得足够高以避免冲突。但这对于生产来说还不够好 - 太多的员工对数据库有写入权限,可能会想要手动添加内容。我希望应用程序足够强大,不会在这种情况下死亡和爆炸。
答案 0 :(得分:3)
为手动ID使用负值。 Hibernate不应该产生负面的。
可选地,使用您自己的id生成器跳过特定范围(或跳过表示可被7整除的数字;某些此类方案)。
样品ID生成器:
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.IdentifierGenerator;
public class MyGenerator implements IdentifierGenerator {
public Serializable generate(SessionImplementor session, Object object)
throws HibernateException {
return 1; // TODO: Your scheme to create an Integer;
}
}
使用此注释如下:
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "myid")
@GenericGenerator(name = "myid", strategy = "com.x.y.z.MyDGenerator")
public int getId() {
return _id;
}
答案 1 :(得分:1)
您也可以将UUID用作id或序列。手动添加的数据也可以参考序列。
答案 2 :(得分:1)
如果您使用Fastnate,则可以使用正确的ID创建import.sql
,足以支持您的JPA模型和数据库。
例如,您可以这样创建实体:
EntitySqlGenerator generator = new EntitySqlGenerator(new FileWriter("import.sql"));
List<DownloadResource> resources = createDownloadResources();
generator.write(resources);
还有一些选项可以创建import.sql
,但是开始时应该足够了。
Fastnate目前没有对Sybase的特殊支持,但对于大多数情况,默认方言(H2)也可以使用。