How to combine manual insertion and JPA Id generation?

I am doing in-container tests with arkillian. I am pre-populating the database adding import.sql

to deployment. During the test, I would like to create some more objects.

Unfortunately this fails with PersistenceException

:

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Unique index or primary key violation: "PRIMARY_KEY_BE ON PUBLIC.KVS_MIPO_DOWNLOAD (ID)"

If I don't dust the DB or save new entities, everything works smoothly.

Id is the only unique field, so I strongly suspect this should be generating id using sequence.

@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;

      

This object is a superclass of another concrete object that does not add any unique attributes.

What can be done to take into account as possible possibilities - insert manually and use the generated identifier?

thank

I am working with JPA 2 through Hibernate 4.0.1 in JBoss 7.1.1. The database is Sybase ASE 15.

EDIT : One workaround I've found so far is to set the IDs of manually added objects high enough to avoid collisions. But this is not enough for production - too many employees have write access to the db and it might be tempting to add stuff manually. I would prefer the app to be robust enough not to die and explode in this case.

+3


source to share


3 answers


Use negative values ​​for your manual IDs. Hibernate shouldn't generate negative ones.

Optionally use your own id generator that skips a specific range (or skips numbers divisible by 7, and some such schemes).

Sample ID generator:



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;
    }
}

      

To use this comment, follow these steps:

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "myid")
@GenericGenerator(name = "myid", strategy = "com.x.y.z.MyDGenerator")
public int getId() {
    return _id;
}

      

+3


source


You can also use the UUID as id, or alternatively a sequence. Manually added data can also refer to a sequence.



+1


source


If you are using Fastnate you can create import.sql

with the correct ids sufficient for your JPA model and your database.

For example, you can create your entities like this:

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

      

There are a few more options for creating import.sql

, but this should be enough to get started.

Fastnate currently has no specific support for Sybase, but the default dialect (H2) will also be used for most cases.

+1


source







All Articles