3

我正在使用 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 中通过 Hibernate 4.0.1 使用 JPA 2。数据库是 Sybase ASE 15。

编辑:到目前为止我发现的一种解决方法是将手动添加的实体的 ID 设置得足够高以避免冲突。但这对于生产来说还不够好——太多的员工对数据库有写访问权,并且可能会想手动添加东西。我希望应用程序足够健壮,不会在这种情况下死亡和爆炸。

4

3 回答 3

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;
}
于 2013-01-18T18:36:30.193 回答
1

您还可以将 UUID 用作 id 或序列。手动添加的数据也可以引用序列。

于 2013-01-18T18:49:00.457 回答
1

如果您使用Fastnate,您可以import.sql使用正确的 ID 创建,足以满足您的 JPA 模型和数据库的需要。

例如,您可以通过以下方式创建实体:

EntitySqlGenerator generator = new EntitySqlGenerator(new FileWriter("import.sql"));
List<DownloadResource> resources = createDownloadResources();
generator.write(resources);

有更多的选项可以创建import.sql,但一开始就足够了。

Fastnate 目前没有对 Sybase 的特殊支持,但对于大多数情况,默认方言 (H2) 也可以使用。

于 2014-12-17T20:34:53.497 回答