如何组合手动插入和JPA Id生成?

时间:2013-01-18 14:53:29

标签: hibernate jpa jpa-2.0 jboss-arquillian

我正在使用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设置得足够高以避免冲突。但这对于生产来说还不够好 - 太多的员工对数据库有写入权限,可能会想要手动添加内容。我希望应用程序足够强大,不会在这种情况下死亡和爆炸。

3 个答案:

答案 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)也可以使用。