Multi part paths in a composite index must have the same length

#1

Hi,

I am trying to create some index in a DB - but I get an exception when i try to commit.

Exception in thread "main" [ObjectDB 2.6.0_01] javax.persistence.PersistenceException
Invalid index path 'tStamp.value / instrumentId' in type Entities.OBN (error 328)
at com.objectdb.jpa.EMImpl.createQuery(EMImpl.java:958)

 

Here is how the class of the persisted object looks like

@Entity
@Index(members={"tStamp.value", "instrumentId"})
public class OBN implements Serializable{
    private static final long serialVersionUID = 998L;
    @Id @GeneratedValue long id;
    @Index private Long instrumentId;
    private SafeLong tStamp;

The SafeLong class is a very simple wrapper of a long - 

@Embeddable
public class SafeLong implements Serializable, Comparable<SafeLong>{
    public long value;

According to the doc - what i am doing is not allowed - but i don't see why it is not possible as my SafeLong class is just a simple wrapper.

Multi part paths in a composite index must have the same length. Therefore, the following index definition is invalid:

@Entity
@Index(members={"lastName", "address.city"}) // INVALID
public class Employee {
    String firstName;
    String lastName;
    Address address;
     :
}

Thanks

EKK

 

#2

You are right. There is no real technical issue with enabling such an index.

A composite index with components of different lengths is forbidden because it may cause difficulties when the components are multi value fields, unlike your simple example.

Build 2.6.0_02 contains a temporary option for disabling this check and error, as demonstrated by the following test case (which fails with 2.6.0_01 and passes with build 2.6.0_02):

import javax.jdo.annotations.Index;
import javax.persistence.*;


public class T1589 {

    public static void main(String[] args) {

        System.setProperty("objectdb.temp.flexible-composite-index", "true");
       
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:$objectdb/db/test.tmp;drop");
        EntityManager em = emf.createEntityManager();
       
        em.getTransaction().begin();
        em.persist(new OBN(1));
        em.persist(new OBN(2));
        em.persist(new OBN(3));
        em.getTransaction().commit();
       
        em.close();
        emf.close();
    }

    @Entity
    @Index(members={"tStamp.value", "instrumentId"})
    public static class OBN {
        @Id @GeneratedValue long id;
        private Long instrumentId;
        private SafeLong tStamp;
        public OBN(int value) {
            instrumentId = Long.valueOf(value);
            tStamp = new SafeLong(value);
        }
    }
   
    @Embeddable
    public static class SafeLong {
        public long value;
        public SafeLong(int value) {
            this.value = value;
        }
    }   
}
ObjectDB Support

Reply