Search in sources :

Example 41 with OObjectDatabaseTx

use of com.orientechnologies.orient.object.db.OObjectDatabaseTx in project orientdb by orientechnologies.

the class TransactionConsistencyTest method testRollbackWithRemove.

/**
   * When calling .remove(o) on a collection, the row corresponding to o is deleted and not restored when the transaction is rolled
   * back.
   * 
   * Commented code after data model change to work around this problem.
   */
@SuppressWarnings("unused")
@Test
public void testRollbackWithRemove() {
    // check if the database exists and clean before running tests
    OObjectDatabaseTx database = new OObjectDatabaseTx(url);
    database.open("admin", "admin");
    try {
        Account account = new Account();
        account.setName("John Grisham");
        account = database.save(account);
        Address address1 = new Address();
        address1.setStreet("Mulholland drive");
        Address address2 = new Address();
        address2.setStreet("Via Veneto");
        List<Address> addresses = new ArrayList<Address>();
        addresses.add(address1);
        addresses.add(address2);
        account.setAddresses(addresses);
        account = database.save(account);
        database.commit();
        String originalName = account.getName();
        database.begin(TXTYPE.OPTIMISTIC);
        Assert.assertEquals(account.getAddresses().size(), 2);
        // delete one of the objects in the Books collection to see how rollback behaves
        account.getAddresses().remove(1);
        Assert.assertEquals(account.getAddresses().size(), 1);
        // change an attribute to see if the change is rolled back
        account.setName("New Name");
        account = database.save(account);
        // before rollback this is fine because one of the books was removed
        Assert.assertEquals(account.getAddresses().size(), 1);
        // rollback the transaction
        database.rollback();
        // ignore cache, get a copy of author from the datastore
        account = database.reload(account, true);
        // this is fine, author still linked to 2 books
        Assert.assertEquals(account.getAddresses().size(), 2);
        // name is restored
        Assert.assertEquals(account.getName(), originalName);
        int bookCount = 0;
        for (Address b : database.browseClass(Address.class)) {
            if (b.getStreet().equals("Mulholland drive") || b.getStreet().equals("Via Veneto"))
                bookCount++;
        }
        // this fails, only 1 entry in the datastore :(
        Assert.assertEquals(bookCount, 2);
    } finally {
        database.close();
    }
}
Also used : Account(com.orientechnologies.orient.test.domain.business.Account) Address(com.orientechnologies.orient.test.domain.business.Address) OObjectDatabaseTx(com.orientechnologies.orient.object.db.OObjectDatabaseTx) ArrayList(java.util.ArrayList) Test(org.testng.annotations.Test) DatabaseAbstractTest(com.orientechnologies.DatabaseAbstractTest)

Example 42 with OObjectDatabaseTx

use of com.orientechnologies.orient.object.db.OObjectDatabaseTx in project orientdb by orientechnologies.

the class OServerTest method testRestart.

/**
   * Test for https://github.com/orientechnologies/orientdb/issues/1667
   */
@Test
public void testRestart() throws Exception {
    // set ORIENTDB_HOME
    final String buildDirectory = System.getProperty("buildDirectory", ".");
    System.setProperty("ORIENTDB_HOME", buildDirectory + File.separator + OServerTest.class.getSimpleName());
    OLogManager.instance().info(this, "ORIENTDB_HOME: " + System.getProperty("ORIENTDB_HOME"));
    // loop for start & stop server
    for (int i = 0; i < 5; i++) {
        OLogManager.instance().info(this, "Iteration " + i);
        OServer server = new OServer(false).activate();
        // create database if does not exist
        OObjectDatabaseTx database = new OObjectDatabaseTx("plocal:" + System.getProperty("ORIENTDB_HOME") + "/test-db");
        if (!database.exists())
            database.create();
        database.open("admin", "admin");
        database.countClass("ouser");
        database.close();
        server.shutdown();
    }
}
Also used : OServer(com.orientechnologies.orient.server.OServer) OObjectDatabaseTx(com.orientechnologies.orient.object.db.OObjectDatabaseTx) Test(org.testng.annotations.Test)

Example 43 with OObjectDatabaseTx

use of com.orientechnologies.orient.object.db.OObjectDatabaseTx in project orientdb by orientechnologies.

the class OObjectEntitySerializer method registerClass.

/**
   * Registers the class informations that will be used in serialization, deserialization and lazy loading of it. If already
   * registered does nothing.
   *
   * @param iClass
   *          :- the Class<?> to register
   * @param forceReload whether or not to force the reload of the schema before registering
   */
@SuppressWarnings("unchecked")
public static synchronized void registerClass(final Class<?> iClass, boolean forceReload) {
    if (!ODatabaseRecordThreadLocal.INSTANCE.isDefined() || ODatabaseRecordThreadLocal.INSTANCE.get().isClosed())
        return;
    final OObjectEntitySerializedSchema serializedSchema = getCurrentSerializedSchema();
    if (serializedSchema == null)
        return;
    if (Proxy.class.isAssignableFrom(iClass) || iClass.isEnum() || OReflectionHelper.isJavaType(iClass) || iClass.isAnonymousClass() || serializedSchema.classes.contains(iClass)) {
        return;
    }
    boolean reloadSchema = false;
    boolean automaticSchemaGeneration = false;
    final ODatabaseDocumentInternal db = ODatabaseRecordThreadLocal.INSTANCE.get();
    final OSchema oSchema = db.getMetadata().getSchema();
    if (forceReload) {
        oSchema.reload();
    }
    if (!oSchema.existsClass(iClass.getSimpleName())) {
        if (Modifier.isAbstract(iClass.getModifiers()))
            oSchema.createAbstractClass(iClass.getSimpleName());
        else
            oSchema.createClass(iClass.getSimpleName());
        reloadSchema = true;
        if (db.getDatabaseOwner() instanceof OObjectDatabaseTx)
            automaticSchemaGeneration = ((OObjectDatabaseTx) db.getDatabaseOwner()).isAutomaticSchemaGeneration();
    }
    for (Class<?> currentClass = iClass; currentClass != Object.class; ) {
        if (!serializedSchema.classes.contains(currentClass)) {
            serializedSchema.classes.add(currentClass);
            Class<?> fieldType;
            for (Field f : currentClass.getDeclaredFields()) {
                final String fieldName = f.getName();
                final int fieldModifier = f.getModifiers();
                boolean transientField = false;
                if (Modifier.isStatic(fieldModifier) || Modifier.isFinal(fieldModifier) || Modifier.isNative(fieldModifier) || Modifier.isTransient(fieldModifier)) {
                    List<String> classTransientFields = serializedSchema.transientFields.get(currentClass);
                    if (classTransientFields == null)
                        classTransientFields = new ArrayList<String>();
                    classTransientFields.add(fieldName);
                    serializedSchema.transientFields.put(currentClass, classTransientFields);
                    transientField = true;
                }
                if (fieldName.equals("this$0")) {
                    List<String> classTransientFields = serializedSchema.transientFields.get(currentClass);
                    if (classTransientFields == null)
                        classTransientFields = new ArrayList<String>();
                    classTransientFields.add(fieldName);
                    serializedSchema.transientFields.put(currentClass, classTransientFields);
                    transientField = true;
                }
                if (OObjectSerializerHelper.jpaTransientClass != null) {
                    Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaTransientClass);
                    if (ann != null) {
                        // @Transient DEFINED
                        List<String> classTransientFields = serializedSchema.transientFields.get(currentClass);
                        if (classTransientFields == null)
                            classTransientFields = new ArrayList<String>();
                        classTransientFields.add(fieldName);
                        serializedSchema.transientFields.put(currentClass, classTransientFields);
                        transientField = true;
                    }
                }
                if (!transientField) {
                    List<String> allClassFields = serializedSchema.allFields.get(currentClass);
                    if (allClassFields == null)
                        allClassFields = new ArrayList<String>();
                    allClassFields.add(fieldName);
                    serializedSchema.allFields.put(currentClass, allClassFields);
                }
                if (OObjectSerializerHelper.jpaOneToOneClass != null) {
                    Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaOneToOneClass);
                    if (ann != null) {
                        // @OneToOne DEFINED
                        OneToOne oneToOne = ((OneToOne) ann);
                        if (checkCascadeDelete(oneToOne)) {
                            addCascadeDeleteField(currentClass, fieldName);
                        }
                        if (checkFetchLazy(oneToOne)) {
                            addFetchLazyField(currentClass, fieldName);
                        }
                    }
                }
                if (OObjectSerializerHelper.jpaOneToManyClass != null) {
                    Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaOneToManyClass);
                    if (ann != null) {
                        // @OneToMany DEFINED
                        OneToMany oneToMany = ((OneToMany) ann);
                        if (checkCascadeDelete(oneToMany)) {
                            addCascadeDeleteField(currentClass, fieldName);
                        }
                    }
                }
                if (OObjectSerializerHelper.jpaManyToManyClass != null) {
                    Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaManyToManyClass);
                    if (ann != null) {
                        // @OneToMany DEFINED
                        ManyToMany manyToMany = ((ManyToMany) ann);
                        if (checkCascadeDelete(manyToMany)) {
                            addCascadeDeleteField(currentClass, fieldName);
                        }
                    }
                }
                fieldType = f.getType();
                if (Collection.class.isAssignableFrom(fieldType) || fieldType.isArray() || Map.class.isAssignableFrom(fieldType)) {
                    fieldType = OReflectionHelper.getGenericMultivalueType(f);
                }
                if (isToSerialize(fieldType)) {
                    Map<Field, Class<?>> serializeClass = serializedSchema.serializedFields.get(currentClass);
                    if (serializeClass == null)
                        serializeClass = new HashMap<Field, Class<?>>();
                    serializeClass.put(f, fieldType);
                    serializedSchema.serializedFields.put(currentClass, serializeClass);
                }
                // CHECK FOR DIRECT-BINDING
                boolean directBinding = true;
                if (f.getAnnotation(OAccess.class) == null || f.getAnnotation(OAccess.class).value() == OAccess.OAccessType.PROPERTY)
                    directBinding = true;
                else // JPA 2+ AVAILABLE?
                if (OObjectSerializerHelper.jpaAccessClass != null) {
                    Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaAccessClass);
                    if (ann != null) {
                        directBinding = true;
                    }
                }
                if (directBinding) {
                    List<String> classDirectAccessFields = serializedSchema.directAccessFields.get(currentClass);
                    if (classDirectAccessFields == null)
                        classDirectAccessFields = new ArrayList<String>();
                    classDirectAccessFields.add(fieldName);
                    serializedSchema.directAccessFields.put(currentClass, classDirectAccessFields);
                }
                if (f.getAnnotation(ODocumentInstance.class) != null)
                    // BOUND DOCUMENT ON IT
                    serializedSchema.boundDocumentFields.put(currentClass, f);
                boolean idFound = false;
                if (f.getAnnotation(OId.class) != null) {
                    // RECORD ID
                    serializedSchema.fieldIds.put(currentClass, f);
                    idFound = true;
                } else // JPA 1+ AVAILABLE?
                if (OObjectSerializerHelper.jpaIdClass != null && f.getAnnotation(OObjectSerializerHelper.jpaIdClass) != null) {
                    // RECORD ID
                    serializedSchema.fieldIds.put(currentClass, f);
                    idFound = true;
                }
                if (idFound) {
                    // CHECK FOR TYPE
                    if (fieldType.isPrimitive())
                        OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be a literal to manage the Record Id", f.toString());
                    else if (!ORID.class.isAssignableFrom(fieldType) && fieldType != String.class && fieldType != Object.class && !Number.class.isAssignableFrom(fieldType))
                        OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be managed as type: %s", f.toString(), fieldType);
                }
                boolean vFound = false;
                if (f.getAnnotation(OVersion.class) != null) {
                    // RECORD ID
                    serializedSchema.fieldVersions.put(currentClass, f);
                    vFound = true;
                } else // JPA 1+ AVAILABLE?
                if (OObjectSerializerHelper.jpaVersionClass != null && f.getAnnotation(OObjectSerializerHelper.jpaVersionClass) != null) {
                    // RECORD ID
                    serializedSchema.fieldVersions.put(currentClass, f);
                    vFound = true;
                }
                if (vFound) {
                    // CHECK FOR TYPE
                    if (fieldType.isPrimitive())
                        OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be a literal to manage the Version", f.toString());
                    else if (fieldType != String.class && fieldType != Object.class && !Number.class.isAssignableFrom(fieldType))
                        OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be managed as type: %s", f.toString(), fieldType);
                }
                // JPA 1+ AVAILABLE?
                if (OObjectSerializerHelper.jpaEmbeddedClass != null && f.getAnnotation(OObjectSerializerHelper.jpaEmbeddedClass) != null) {
                    List<String> classEmbeddedFields = serializedSchema.embeddedFields.get(currentClass);
                    if (classEmbeddedFields == null)
                        classEmbeddedFields = new ArrayList<String>();
                    classEmbeddedFields.add(fieldName);
                    serializedSchema.embeddedFields.put(currentClass, classEmbeddedFields);
                }
            }
            registerCallbacks(currentClass);
        }
        if (automaticSchemaGeneration && !currentClass.equals(Object.class) && !currentClass.equals(ODocument.class)) {
            ((OSchemaProxyObject) db.getDatabaseOwner().getMetadata().getSchema()).generateSchema(currentClass, db);
        }
        String iClassName = currentClass.getSimpleName();
        currentClass = currentClass.getSuperclass();
        if (currentClass == null || currentClass.equals(ODocument.class))
            // POJO EXTENDS ODOCUMENT: SPECIAL CASE: AVOID TO CONSIDER
            // ODOCUMENT FIELDS
            currentClass = Object.class;
        if (!currentClass.equals(Object.class)) {
            OClass oSuperClass;
            OClass currentOClass = oSchema.getClass(iClassName);
            if (!oSchema.existsClass(currentClass.getSimpleName())) {
                OSchema schema = oSchema;
                if (Modifier.isAbstract(currentClass.getModifiers())) {
                    oSuperClass = schema.createAbstractClass(currentClass.getSimpleName());
                } else {
                    oSuperClass = schema.createClass(currentClass.getSimpleName());
                }
                reloadSchema = true;
            } else {
                oSuperClass = oSchema.getClass(currentClass.getSimpleName());
            }
            if (!currentOClass.getSuperClasses().contains(oSuperClass)) {
                currentOClass.setSuperClasses(Arrays.asList(oSuperClass));
                reloadSchema = true;
            }
        }
    }
    if (reloadSchema) {
        oSchema.save();
        oSchema.reload();
    }
}
Also used : OSchema(com.orientechnologies.orient.core.metadata.schema.OSchema) HashMap(java.util.HashMap) OSchemaProxyObject(com.orientechnologies.orient.object.metadata.schema.OSchemaProxyObject) ArrayList(java.util.ArrayList) OAccess(com.orientechnologies.orient.core.annotation.OAccess) OId(com.orientechnologies.orient.core.annotation.OId) ODatabaseDocumentInternal(com.orientechnologies.orient.core.db.ODatabaseDocumentInternal) Field(java.lang.reflect.Field) OneToOne(javax.persistence.OneToOne) OClass(com.orientechnologies.orient.core.metadata.schema.OClass) ORID(com.orientechnologies.orient.core.id.ORID) ODocument(com.orientechnologies.orient.core.record.impl.ODocument) OVersion(com.orientechnologies.orient.core.annotation.OVersion) OObjectDatabaseTx(com.orientechnologies.orient.object.db.OObjectDatabaseTx) ManyToMany(javax.persistence.ManyToMany) ODocumentInstance(com.orientechnologies.orient.core.annotation.ODocumentInstance) OneToMany(javax.persistence.OneToMany) Annotation(java.lang.annotation.Annotation) OObjectSerializerHelper(com.orientechnologies.orient.object.serialization.OObjectSerializerHelper) OClass(com.orientechnologies.orient.core.metadata.schema.OClass) ProxyObject(javassist.util.proxy.ProxyObject) ODatabaseObject(com.orientechnologies.orient.core.db.object.ODatabaseObject) OSchemaProxyObject(com.orientechnologies.orient.object.metadata.schema.OSchemaProxyObject) ORecordLazyMap(com.orientechnologies.orient.core.db.record.ORecordLazyMap) Map(java.util.Map) OTrackedMap(com.orientechnologies.orient.core.db.record.OTrackedMap) HashMap(java.util.HashMap) OObjectLazyMap(com.orientechnologies.orient.object.db.OObjectLazyMap)

Example 44 with OObjectDatabaseTx

use of com.orientechnologies.orient.object.db.OObjectDatabaseTx in project orientdb by orientechnologies.

the class OSchemaProxyObject method synchronizeSchema.

/**
   * Checks if all registered entities has schema generated, if not it generates it
   */
public synchronized void synchronizeSchema() {
    OObjectDatabaseTx database = ((OObjectDatabaseTx) ODatabaseRecordThreadLocal.INSTANCE.get().getDatabaseOwner());
    Collection<Class<?>> registeredEntities = database.getEntityManager().getRegisteredEntities();
    boolean automaticSchemaGeneration = database.isAutomaticSchemaGeneration();
    boolean reloadSchema = false;
    for (Class<?> iClass : registeredEntities) {
        if (Proxy.class.isAssignableFrom(iClass) || iClass.isEnum() || OReflectionHelper.isJavaType(iClass) || iClass.isAnonymousClass())
            return;
        if (!database.getMetadata().getSchema().existsClass(iClass.getSimpleName())) {
            database.getMetadata().getSchema().createClass(iClass.getSimpleName());
            reloadSchema = true;
        }
        for (Class<?> currentClass = iClass; currentClass != Object.class; ) {
            if (automaticSchemaGeneration && !currentClass.equals(Object.class) && !currentClass.equals(ODocument.class)) {
                ((OSchemaProxyObject) database.getMetadata().getSchema()).generateSchema(currentClass, database.getUnderlying());
            }
            String iClassName = currentClass.getSimpleName();
            currentClass = currentClass.getSuperclass();
            if (currentClass == null || currentClass.equals(ODocument.class))
                // POJO EXTENDS ODOCUMENT: SPECIAL CASE: AVOID TO CONSIDER
                // ODOCUMENT FIELDS
                currentClass = Object.class;
            if (database != null && !database.isClosed() && !currentClass.equals(Object.class)) {
                OClass oSuperClass;
                OClass currentOClass = database.getMetadata().getSchema().getClass(iClassName);
                if (!database.getMetadata().getSchema().existsClass(currentClass.getSimpleName())) {
                    oSuperClass = database.getMetadata().getSchema().createClass(currentClass.getSimpleName());
                    reloadSchema = true;
                } else {
                    oSuperClass = database.getMetadata().getSchema().getClass(currentClass.getSimpleName());
                    reloadSchema = true;
                }
                if (!currentOClass.getSuperClasses().contains(oSuperClass)) {
                    currentOClass.setSuperClasses(Arrays.asList(oSuperClass));
                    reloadSchema = true;
                }
            }
        }
    }
    if (database != null && !database.isClosed() && reloadSchema) {
        database.getMetadata().getSchema().save();
        database.getMetadata().getSchema().reload();
    }
}
Also used : Proxy(javassist.util.proxy.Proxy) OObjectDatabaseTx(com.orientechnologies.orient.object.db.OObjectDatabaseTx) ODocument(com.orientechnologies.orient.core.record.impl.ODocument)

Example 45 with OObjectDatabaseTx

use of com.orientechnologies.orient.object.db.OObjectDatabaseTx in project orientdb by orientechnologies.

the class OObjectProxyMethodHandlerTest method setUp.

@BeforeClass
protected void setUp() throws Exception {
    databaseTx = new OObjectDatabaseTx("memory:OObjectEnumLazyListTest");
    databaseTx.create();
    databaseTx.getEntityManager().registerEntityClass(EntityWithDifferentFieldTypes.class);
    databaseTx.getEntityManager().registerEntityClass(EmbeddedType1.class);
    databaseTx.getEntityManager().registerEntityClass(EmbeddedType2.class);
    databaseTx.getEntityManager().registerEntityClass(EntityWithEmbeddedFields.class);
    fieldsAndThereDefaultValue = new HashMap<String, Object>();
    fieldsAndThereDefaultValue.put("byteField", Byte.valueOf("0"));
    fieldsAndThereDefaultValue.put("shortField", Short.valueOf("0"));
    fieldsAndThereDefaultValue.put("intField", 0);
    fieldsAndThereDefaultValue.put("longField", 0L);
    fieldsAndThereDefaultValue.put("floatField", 0.0f);
    fieldsAndThereDefaultValue.put("doubleField", 0.0d);
    fieldsAndThereDefaultValue.put("stringField", null);
    fieldsAndThereDefaultValue.put("booleanField", false);
    fieldsAndThereDefaultValue.put("objectField", null);
}
Also used : OObjectDatabaseTx(com.orientechnologies.orient.object.db.OObjectDatabaseTx) BeforeClass(org.testng.annotations.BeforeClass)

Aggregations

OObjectDatabaseTx (com.orientechnologies.orient.object.db.OObjectDatabaseTx)48 Test (org.testng.annotations.Test)25 ORID (com.orientechnologies.orient.core.id.ORID)15 ODocument (com.orientechnologies.orient.core.record.impl.ODocument)14 HashMap (java.util.HashMap)11 HashSet (java.util.HashSet)11 Map (java.util.Map)9 ORecordId (com.orientechnologies.orient.core.id.ORecordId)8 EnumTest (com.orientechnologies.orient.test.domain.base.EnumTest)8 JavaAttachDetachTestClass (com.orientechnologies.orient.test.domain.base.JavaAttachDetachTestClass)8 Planet (com.orientechnologies.orient.test.domain.base.Planet)8 Satellite (com.orientechnologies.orient.test.domain.base.Satellite)8 Child (com.orientechnologies.orient.test.domain.business.Child)8 Set (java.util.Set)8 ArrayList (java.util.ArrayList)5 Proxy (javassist.util.proxy.Proxy)5 BeforeClass (org.testng.annotations.BeforeClass)5 CycleChild (com.orientechnologies.orient.test.domain.cycle.CycleChild)4 GrandChild (com.orientechnologies.orient.test.domain.cycle.GrandChild)4 LazyChild (com.orientechnologies.orient.test.domain.lazy.LazyChild)4