diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/annotations/Cache.java b/src/nl/astraeus/database/annotations/Cache.java index 37d0b43..146e2e0 100644 --- a/src/nl/astraeus/database/annotations/Cache.java +++ b/src/nl/astraeus/database/annotations/Cache.java @@ -11,7 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Cache { - int maxSize() default 1000; + int maxSize() default 100; long maxAge() default 0; } diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/annotations/Cache.java b/src/nl/astraeus/database/annotations/Cache.java index 37d0b43..146e2e0 100644 --- a/src/nl/astraeus/database/annotations/Cache.java +++ b/src/nl/astraeus/database/annotations/Cache.java @@ -11,7 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Cache { - int maxSize() default 1000; + int maxSize() default 100; long maxAge() default 0; } diff --git a/src/nl/astraeus/database/cache/Cache.java b/src/nl/astraeus/database/cache/Cache.java index 1ee71f7..b14e840 100644 --- a/src/nl/astraeus/database/cache/Cache.java +++ b/src/nl/astraeus/database/cache/Cache.java @@ -18,7 +18,7 @@ private Map, ObjectCache> cache = new ConcurrentHashMap<>(); public boolean inCache(Class cls, Long id) { - return cache.get(cls) != null && cache.get(cls).knownObject(id); + return cache.get(cls) != null && cache.get(cls).inCache(id); } public T get(Class cls, Long id) { diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/annotations/Cache.java b/src/nl/astraeus/database/annotations/Cache.java index 37d0b43..146e2e0 100644 --- a/src/nl/astraeus/database/annotations/Cache.java +++ b/src/nl/astraeus/database/annotations/Cache.java @@ -11,7 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Cache { - int maxSize() default 1000; + int maxSize() default 100; long maxAge() default 0; } diff --git a/src/nl/astraeus/database/cache/Cache.java b/src/nl/astraeus/database/cache/Cache.java index 1ee71f7..b14e840 100644 --- a/src/nl/astraeus/database/cache/Cache.java +++ b/src/nl/astraeus/database/cache/Cache.java @@ -18,7 +18,7 @@ private Map, ObjectCache> cache = new ConcurrentHashMap<>(); public boolean inCache(Class cls, Long id) { - return cache.get(cls) != null && cache.get(cls).knownObject(id); + return cache.get(cls) != null && cache.get(cls).inCache(id); } public T get(Class cls, Long id) { diff --git a/src/nl/astraeus/database/cache/ObjectCache.java b/src/nl/astraeus/database/cache/ObjectCache.java index 41d2e7e..38afc67 100644 --- a/src/nl/astraeus/database/cache/ObjectCache.java +++ b/src/nl/astraeus/database/cache/ObjectCache.java @@ -14,7 +14,7 @@ private int maxSize = 100; private long maxAge = 0; - public boolean knownObject(Long id) { + public boolean inCache(Long id) { return cache.get(id) != null; } @@ -33,12 +33,26 @@ ObjectReference ref = cache.get(id); if (ref == null) { - ref = new ObjectReference(object); + ref = new ObjectReference(id, object); cache.put(id, ref); } else { ref.set(object); } + + if (cache.size() > maxSize) { + ObjectReference delete = null; + + for (ObjectReference objRef : cache.values()) { + if (delete == null || delete.getLastAccessTime() > objRef.getLastAccessTime()) { + delete = objRef; + } + } + + if (delete != null) { + cache.remove(delete.getId()); + } + } } public int getNumberCached() { diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/annotations/Cache.java b/src/nl/astraeus/database/annotations/Cache.java index 37d0b43..146e2e0 100644 --- a/src/nl/astraeus/database/annotations/Cache.java +++ b/src/nl/astraeus/database/annotations/Cache.java @@ -11,7 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Cache { - int maxSize() default 1000; + int maxSize() default 100; long maxAge() default 0; } diff --git a/src/nl/astraeus/database/cache/Cache.java b/src/nl/astraeus/database/cache/Cache.java index 1ee71f7..b14e840 100644 --- a/src/nl/astraeus/database/cache/Cache.java +++ b/src/nl/astraeus/database/cache/Cache.java @@ -18,7 +18,7 @@ private Map, ObjectCache> cache = new ConcurrentHashMap<>(); public boolean inCache(Class cls, Long id) { - return cache.get(cls) != null && cache.get(cls).knownObject(id); + return cache.get(cls) != null && cache.get(cls).inCache(id); } public T get(Class cls, Long id) { diff --git a/src/nl/astraeus/database/cache/ObjectCache.java b/src/nl/astraeus/database/cache/ObjectCache.java index 41d2e7e..38afc67 100644 --- a/src/nl/astraeus/database/cache/ObjectCache.java +++ b/src/nl/astraeus/database/cache/ObjectCache.java @@ -14,7 +14,7 @@ private int maxSize = 100; private long maxAge = 0; - public boolean knownObject(Long id) { + public boolean inCache(Long id) { return cache.get(id) != null; } @@ -33,12 +33,26 @@ ObjectReference ref = cache.get(id); if (ref == null) { - ref = new ObjectReference(object); + ref = new ObjectReference(id, object); cache.put(id, ref); } else { ref.set(object); } + + if (cache.size() > maxSize) { + ObjectReference delete = null; + + for (ObjectReference objRef : cache.values()) { + if (delete == null || delete.getLastAccessTime() > objRef.getLastAccessTime()) { + delete = objRef; + } + } + + if (delete != null) { + cache.remove(delete.getId()); + } + } } public int getNumberCached() { diff --git a/src/nl/astraeus/database/cache/ObjectReference.java b/src/nl/astraeus/database/cache/ObjectReference.java index 7779dd1..b3739e9 100644 --- a/src/nl/astraeus/database/cache/ObjectReference.java +++ b/src/nl/astraeus/database/cache/ObjectReference.java @@ -6,18 +6,24 @@ */ public class ObjectReference { + private long id; private T object; private long cachedTime; private long lastAccessTime; private long reads, writes; - public ObjectReference(T object) { + public ObjectReference(long id, T object) { + this.id = id; this.object = object; this.cachedTime = System.currentTimeMillis(); this.reads = 0; this.writes = 0; } + public long getId() { + return id; + } + public T get() { reads++; lastAccessTime = System.currentTimeMillis(); diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/annotations/Cache.java b/src/nl/astraeus/database/annotations/Cache.java index 37d0b43..146e2e0 100644 --- a/src/nl/astraeus/database/annotations/Cache.java +++ b/src/nl/astraeus/database/annotations/Cache.java @@ -11,7 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Cache { - int maxSize() default 1000; + int maxSize() default 100; long maxAge() default 0; } diff --git a/src/nl/astraeus/database/cache/Cache.java b/src/nl/astraeus/database/cache/Cache.java index 1ee71f7..b14e840 100644 --- a/src/nl/astraeus/database/cache/Cache.java +++ b/src/nl/astraeus/database/cache/Cache.java @@ -18,7 +18,7 @@ private Map, ObjectCache> cache = new ConcurrentHashMap<>(); public boolean inCache(Class cls, Long id) { - return cache.get(cls) != null && cache.get(cls).knownObject(id); + return cache.get(cls) != null && cache.get(cls).inCache(id); } public T get(Class cls, Long id) { diff --git a/src/nl/astraeus/database/cache/ObjectCache.java b/src/nl/astraeus/database/cache/ObjectCache.java index 41d2e7e..38afc67 100644 --- a/src/nl/astraeus/database/cache/ObjectCache.java +++ b/src/nl/astraeus/database/cache/ObjectCache.java @@ -14,7 +14,7 @@ private int maxSize = 100; private long maxAge = 0; - public boolean knownObject(Long id) { + public boolean inCache(Long id) { return cache.get(id) != null; } @@ -33,12 +33,26 @@ ObjectReference ref = cache.get(id); if (ref == null) { - ref = new ObjectReference(object); + ref = new ObjectReference(id, object); cache.put(id, ref); } else { ref.set(object); } + + if (cache.size() > maxSize) { + ObjectReference delete = null; + + for (ObjectReference objRef : cache.values()) { + if (delete == null || delete.getLastAccessTime() > objRef.getLastAccessTime()) { + delete = objRef; + } + } + + if (delete != null) { + cache.remove(delete.getId()); + } + } } public int getNumberCached() { diff --git a/src/nl/astraeus/database/cache/ObjectReference.java b/src/nl/astraeus/database/cache/ObjectReference.java index 7779dd1..b3739e9 100644 --- a/src/nl/astraeus/database/cache/ObjectReference.java +++ b/src/nl/astraeus/database/cache/ObjectReference.java @@ -6,18 +6,24 @@ */ public class ObjectReference { + private long id; private T object; private long cachedTime; private long lastAccessTime; private long reads, writes; - public ObjectReference(T object) { + public ObjectReference(long id, T object) { + this.id = id; this.object = object; this.cachedTime = System.currentTimeMillis(); this.reads = 0; this.writes = 0; } + public long getId() { + return id; + } + public T get() { reads++; lastAccessTime = System.currentTimeMillis(); diff --git a/test/nl/astraeus/database/TestCache.java b/test/nl/astraeus/database/TestCache.java new file mode 100644 index 0000000..adbe52b --- /dev/null +++ b/test/nl/astraeus/database/TestCache.java @@ -0,0 +1,55 @@ +package nl.astraeus.database; + +import nl.astraeus.database.cache.Cache; +import nl.astraeus.database.cache.ObjectCache; +import nl.astraeus.database.test.model.Company; +import nl.astraeus.database.test.model.Info; +import nl.astraeus.database.test.model.Person; + +import java.util.List; +import java.util.Map; + +/** + * Date: 11/16/13 + * Time: 12:27 AM + */ +public class TestCache { + + public static void main(String [] args) { + List persons = Persister.selectAll(Person.class); + List company = Persister.selectAll(Company.class); + List infos = Persister.selectAll(Info.class); + + if (persons.size() == 0) { + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + insert(new Person("Rien", 40, "Rozendael")); + insert(new Person("Jan", 32, "Straat")); + insert(new Person("Piet", 26, "Weg")); + insert(new Person("Klaas", 10, "Pad")); + insert(new Person("Rien", 40, "Rozendael")); + insert(new Person("Jan", 32, "Straat")); + insert(new Person("Piet", 26, "Weg")); + insert(new Person("Klaas", 10, "Pad")); + } + }); + + persons = Persister.selectAll(Person.class); + } + + Map, ObjectCache> cache = Cache.get().getCache(); + + for (Class cls : cache.keySet()) { + System.out.println("# Cached "+cls.getSimpleName()+": " + cache.get(cls).getNumberCached()); + } + + Persister.selectAll(Person.class); + + for (Class cls : cache.keySet()) { + System.out.println("# Cached "+cls.getSimpleName()+": " + cache.get(cls).getNumberCached()); + } + + } + +} diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/annotations/Cache.java b/src/nl/astraeus/database/annotations/Cache.java index 37d0b43..146e2e0 100644 --- a/src/nl/astraeus/database/annotations/Cache.java +++ b/src/nl/astraeus/database/annotations/Cache.java @@ -11,7 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Cache { - int maxSize() default 1000; + int maxSize() default 100; long maxAge() default 0; } diff --git a/src/nl/astraeus/database/cache/Cache.java b/src/nl/astraeus/database/cache/Cache.java index 1ee71f7..b14e840 100644 --- a/src/nl/astraeus/database/cache/Cache.java +++ b/src/nl/astraeus/database/cache/Cache.java @@ -18,7 +18,7 @@ private Map, ObjectCache> cache = new ConcurrentHashMap<>(); public boolean inCache(Class cls, Long id) { - return cache.get(cls) != null && cache.get(cls).knownObject(id); + return cache.get(cls) != null && cache.get(cls).inCache(id); } public T get(Class cls, Long id) { diff --git a/src/nl/astraeus/database/cache/ObjectCache.java b/src/nl/astraeus/database/cache/ObjectCache.java index 41d2e7e..38afc67 100644 --- a/src/nl/astraeus/database/cache/ObjectCache.java +++ b/src/nl/astraeus/database/cache/ObjectCache.java @@ -14,7 +14,7 @@ private int maxSize = 100; private long maxAge = 0; - public boolean knownObject(Long id) { + public boolean inCache(Long id) { return cache.get(id) != null; } @@ -33,12 +33,26 @@ ObjectReference ref = cache.get(id); if (ref == null) { - ref = new ObjectReference(object); + ref = new ObjectReference(id, object); cache.put(id, ref); } else { ref.set(object); } + + if (cache.size() > maxSize) { + ObjectReference delete = null; + + for (ObjectReference objRef : cache.values()) { + if (delete == null || delete.getLastAccessTime() > objRef.getLastAccessTime()) { + delete = objRef; + } + } + + if (delete != null) { + cache.remove(delete.getId()); + } + } } public int getNumberCached() { diff --git a/src/nl/astraeus/database/cache/ObjectReference.java b/src/nl/astraeus/database/cache/ObjectReference.java index 7779dd1..b3739e9 100644 --- a/src/nl/astraeus/database/cache/ObjectReference.java +++ b/src/nl/astraeus/database/cache/ObjectReference.java @@ -6,18 +6,24 @@ */ public class ObjectReference { + private long id; private T object; private long cachedTime; private long lastAccessTime; private long reads, writes; - public ObjectReference(T object) { + public ObjectReference(long id, T object) { + this.id = id; this.object = object; this.cachedTime = System.currentTimeMillis(); this.reads = 0; this.writes = 0; } + public long getId() { + return id; + } + public T get() { reads++; lastAccessTime = System.currentTimeMillis(); diff --git a/test/nl/astraeus/database/TestCache.java b/test/nl/astraeus/database/TestCache.java new file mode 100644 index 0000000..adbe52b --- /dev/null +++ b/test/nl/astraeus/database/TestCache.java @@ -0,0 +1,55 @@ +package nl.astraeus.database; + +import nl.astraeus.database.cache.Cache; +import nl.astraeus.database.cache.ObjectCache; +import nl.astraeus.database.test.model.Company; +import nl.astraeus.database.test.model.Info; +import nl.astraeus.database.test.model.Person; + +import java.util.List; +import java.util.Map; + +/** + * Date: 11/16/13 + * Time: 12:27 AM + */ +public class TestCache { + + public static void main(String [] args) { + List persons = Persister.selectAll(Person.class); + List company = Persister.selectAll(Company.class); + List infos = Persister.selectAll(Info.class); + + if (persons.size() == 0) { + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + insert(new Person("Rien", 40, "Rozendael")); + insert(new Person("Jan", 32, "Straat")); + insert(new Person("Piet", 26, "Weg")); + insert(new Person("Klaas", 10, "Pad")); + insert(new Person("Rien", 40, "Rozendael")); + insert(new Person("Jan", 32, "Straat")); + insert(new Person("Piet", 26, "Weg")); + insert(new Person("Klaas", 10, "Pad")); + } + }); + + persons = Persister.selectAll(Person.class); + } + + Map, ObjectCache> cache = Cache.get().getCache(); + + for (Class cls : cache.keySet()) { + System.out.println("# Cached "+cls.getSimpleName()+": " + cache.get(cls).getNumberCached()); + } + + Persister.selectAll(Person.class); + + for (Class cls : cache.keySet()) { + System.out.println("# Cached "+cls.getSimpleName()+": " + cache.get(cls).getNumberCached()); + } + + } + +} diff --git a/test/nl/astraeus/database/TestOrphan.java b/test/nl/astraeus/database/TestOrphan.java new file mode 100644 index 0000000..a7ebda5 --- /dev/null +++ b/test/nl/astraeus/database/TestOrphan.java @@ -0,0 +1,50 @@ +package nl.astraeus.database; + +import nl.astraeus.database.test.model.Company; +import nl.astraeus.database.test.model.Person; + +/** + * Date: 11/16/13 + * Time: 12:27 AM + */ +public class TestOrphan { + + public static void main(String [] args) { + final Person person = new Person("Test", 44, "Somewhere"); + final Company company = new Company("Some company"); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + person.setCompany(company); + + insert(person); + } + }); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + delete(company); + } + }); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + Person found = find(Person.class, person.getId()); + + System.out.println("Found: "+found.getName()); + System.out.println("Company: "+found.getCompany()); + } + }); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + delete(person); + } + }); + } + +} diff --git a/src/nl/astraeus/database/FieldMetaData.java b/src/nl/astraeus/database/FieldMetaData.java index bb18eff..3a90354 100644 --- a/src/nl/astraeus/database/FieldMetaData.java +++ b/src/nl/astraeus/database/FieldMetaData.java @@ -3,6 +3,8 @@ import nl.astraeus.database.annotations.*; import nl.astraeus.template.EscapeMode; import nl.astraeus.template.SimpleTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.lang.reflect.Field; @@ -16,6 +18,7 @@ * Time: 8:59 PM */ public class FieldMetaData { + private final static Logger logger = LoggerFactory.getLogger(FieldMetaData.class); public static enum ColumnType { BASIC, @@ -150,6 +153,10 @@ return primaryKey; } + public ColumnType getType() { + return type; + } + public Field getField() { return field; } @@ -193,6 +200,7 @@ public void set(PreparedStatement statement, int index, Object obj) throws SQLException { Object value = get(obj); MetaData metaData = null; + Long id = null; if (value == null) { switch(type) { @@ -230,14 +238,23 @@ break; case REFERENCE: metaData = MetaDataHandler.get().getMetaData(value.getClass()); - statement.setLong(index, metaData.getId(value)); + + id = metaData.getId(value); + + if (id == null) { + Persister.insert(value); + + id = metaData.getId(value); + } + + statement.setLong(index, id); break; case COLLECTION: metaData = MetaDataHandler.get().getMetaData(collectionClass); java.util.Collection c = (java.util.Collection)value; ByteBuffer buffer = ByteBuffer.allocate(c.size() * 8); for (Object o : c) { - Long id = metaData.getId(o); + id = metaData.getId(o); if (id == null || id == 0) { Persister.insert(o); @@ -280,7 +297,13 @@ case REFERENCE: id = rs.getLong(index); - set(obj, Persister.find(javaType, id)); + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(obj, object); break; case COLLECTION: Blob blob = rs.getBlob(index); @@ -300,4 +323,23 @@ } } + + public void reloadReference(T result) { + Object current = get(result); + + if (current != null) { + MetaData meta = MetaDataHandler.get().getMetaData(current.getClass()); + + Long id = meta.getId(current); + + Object object = Persister.find(javaType, id); + + if (object == null) { + logger.warn("Orphan detected "+javaType.getSimpleName()+":"+id); + } + + set(result, object); + } + } + } diff --git a/src/nl/astraeus/database/MetaData.java b/src/nl/astraeus/database/MetaData.java index cc9ea58..4da2b42 100644 --- a/src/nl/astraeus/database/MetaData.java +++ b/src/nl/astraeus/database/MetaData.java @@ -1,5 +1,6 @@ package nl.astraeus.database; +import nl.astraeus.database.annotations.Cache; import nl.astraeus.database.annotations.Id; import nl.astraeus.database.annotations.Table; import nl.astraeus.database.sql.TemplateHandler; @@ -37,6 +38,13 @@ tableName = cls.getSimpleName(); } + Cache cache = cls.getAnnotation(Cache.class); + + if (cache != null) { + nl.astraeus.database.cache.Cache.get().setMaxSize(cls, cache.maxSize()); + nl.astraeus.database.cache.Cache.get().setMaxAge(cls, cache.maxAge()); + } + Field [] fields = cls.getDeclaredFields(); this.fieldsMetaData = new FieldMetaData[fields.length]; int index = 0; @@ -173,7 +181,7 @@ connection = Persister.getNewConnection(); String sql = createTemplate.render(model); - System.out.println("Executing:\n"+sql); + logger.info("Executing:\n" + sql); statement = connection.prepareStatement(sql); statement.execute(); @@ -474,4 +482,12 @@ public Long getId(Object object) { return (Long)pk.get(object); } + + public void reloadReferences(T result) { + for (FieldMetaData field : fieldsMetaData) { + if (field.getType() == FieldMetaData.ColumnType.REFERENCE) { + field.reloadReference(result); + } + } + } } diff --git a/src/nl/astraeus/database/ObjectPersister.java b/src/nl/astraeus/database/ObjectPersister.java index 78277c5..bde1912 100644 --- a/src/nl/astraeus/database/ObjectPersister.java +++ b/src/nl/astraeus/database/ObjectPersister.java @@ -36,7 +36,6 @@ Long id = metaData.getId(object); metaData.delete(id); - Cache.get().set(object.getClass(), id, null); } diff --git a/src/nl/astraeus/database/Persister.java b/src/nl/astraeus/database/Persister.java index 1cb1339..4a2695f 100644 --- a/src/nl/astraeus/database/Persister.java +++ b/src/nl/astraeus/database/Persister.java @@ -153,7 +153,13 @@ public static T find(Class cls, long id) { if (Cache.get().inCache(cls, id)) { - return Cache.get().get(cls, id); + T result = Cache.get().get(cls, id); + + MetaData meta = MetaDataHandler.get().getMetaData(cls); + + meta.reloadReferences(result); + + return result; } T result = getObjectPersister(cls).find(id); diff --git a/src/nl/astraeus/database/annotations/Cache.java b/src/nl/astraeus/database/annotations/Cache.java index 37d0b43..146e2e0 100644 --- a/src/nl/astraeus/database/annotations/Cache.java +++ b/src/nl/astraeus/database/annotations/Cache.java @@ -11,7 +11,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Cache { - int maxSize() default 1000; + int maxSize() default 100; long maxAge() default 0; } diff --git a/src/nl/astraeus/database/cache/Cache.java b/src/nl/astraeus/database/cache/Cache.java index 1ee71f7..b14e840 100644 --- a/src/nl/astraeus/database/cache/Cache.java +++ b/src/nl/astraeus/database/cache/Cache.java @@ -18,7 +18,7 @@ private Map, ObjectCache> cache = new ConcurrentHashMap<>(); public boolean inCache(Class cls, Long id) { - return cache.get(cls) != null && cache.get(cls).knownObject(id); + return cache.get(cls) != null && cache.get(cls).inCache(id); } public T get(Class cls, Long id) { diff --git a/src/nl/astraeus/database/cache/ObjectCache.java b/src/nl/astraeus/database/cache/ObjectCache.java index 41d2e7e..38afc67 100644 --- a/src/nl/astraeus/database/cache/ObjectCache.java +++ b/src/nl/astraeus/database/cache/ObjectCache.java @@ -14,7 +14,7 @@ private int maxSize = 100; private long maxAge = 0; - public boolean knownObject(Long id) { + public boolean inCache(Long id) { return cache.get(id) != null; } @@ -33,12 +33,26 @@ ObjectReference ref = cache.get(id); if (ref == null) { - ref = new ObjectReference(object); + ref = new ObjectReference(id, object); cache.put(id, ref); } else { ref.set(object); } + + if (cache.size() > maxSize) { + ObjectReference delete = null; + + for (ObjectReference objRef : cache.values()) { + if (delete == null || delete.getLastAccessTime() > objRef.getLastAccessTime()) { + delete = objRef; + } + } + + if (delete != null) { + cache.remove(delete.getId()); + } + } } public int getNumberCached() { diff --git a/src/nl/astraeus/database/cache/ObjectReference.java b/src/nl/astraeus/database/cache/ObjectReference.java index 7779dd1..b3739e9 100644 --- a/src/nl/astraeus/database/cache/ObjectReference.java +++ b/src/nl/astraeus/database/cache/ObjectReference.java @@ -6,18 +6,24 @@ */ public class ObjectReference { + private long id; private T object; private long cachedTime; private long lastAccessTime; private long reads, writes; - public ObjectReference(T object) { + public ObjectReference(long id, T object) { + this.id = id; this.object = object; this.cachedTime = System.currentTimeMillis(); this.reads = 0; this.writes = 0; } + public long getId() { + return id; + } + public T get() { reads++; lastAccessTime = System.currentTimeMillis(); diff --git a/test/nl/astraeus/database/TestCache.java b/test/nl/astraeus/database/TestCache.java new file mode 100644 index 0000000..adbe52b --- /dev/null +++ b/test/nl/astraeus/database/TestCache.java @@ -0,0 +1,55 @@ +package nl.astraeus.database; + +import nl.astraeus.database.cache.Cache; +import nl.astraeus.database.cache.ObjectCache; +import nl.astraeus.database.test.model.Company; +import nl.astraeus.database.test.model.Info; +import nl.astraeus.database.test.model.Person; + +import java.util.List; +import java.util.Map; + +/** + * Date: 11/16/13 + * Time: 12:27 AM + */ +public class TestCache { + + public static void main(String [] args) { + List persons = Persister.selectAll(Person.class); + List company = Persister.selectAll(Company.class); + List infos = Persister.selectAll(Info.class); + + if (persons.size() == 0) { + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + insert(new Person("Rien", 40, "Rozendael")); + insert(new Person("Jan", 32, "Straat")); + insert(new Person("Piet", 26, "Weg")); + insert(new Person("Klaas", 10, "Pad")); + insert(new Person("Rien", 40, "Rozendael")); + insert(new Person("Jan", 32, "Straat")); + insert(new Person("Piet", 26, "Weg")); + insert(new Person("Klaas", 10, "Pad")); + } + }); + + persons = Persister.selectAll(Person.class); + } + + Map, ObjectCache> cache = Cache.get().getCache(); + + for (Class cls : cache.keySet()) { + System.out.println("# Cached "+cls.getSimpleName()+": " + cache.get(cls).getNumberCached()); + } + + Persister.selectAll(Person.class); + + for (Class cls : cache.keySet()) { + System.out.println("# Cached "+cls.getSimpleName()+": " + cache.get(cls).getNumberCached()); + } + + } + +} diff --git a/test/nl/astraeus/database/TestOrphan.java b/test/nl/astraeus/database/TestOrphan.java new file mode 100644 index 0000000..a7ebda5 --- /dev/null +++ b/test/nl/astraeus/database/TestOrphan.java @@ -0,0 +1,50 @@ +package nl.astraeus.database; + +import nl.astraeus.database.test.model.Company; +import nl.astraeus.database.test.model.Person; + +/** + * Date: 11/16/13 + * Time: 12:27 AM + */ +public class TestOrphan { + + public static void main(String [] args) { + final Person person = new Person("Test", 44, "Somewhere"); + final Company company = new Company("Some company"); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + person.setCompany(company); + + insert(person); + } + }); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + delete(company); + } + }); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + Person found = find(Person.class, person.getId()); + + System.out.println("Found: "+found.getName()); + System.out.println("Company: "+found.getCompany()); + } + }); + + Persister.execute(new Persister.Executor() { + @Override + public void execute() { + delete(person); + } + }); + } + +} diff --git a/test/nl/astraeus/database/test/model/Person.java b/test/nl/astraeus/database/test/model/Person.java index abf6d14..66defe9 100644 --- a/test/nl/astraeus/database/test/model/Person.java +++ b/test/nl/astraeus/database/test/model/Person.java @@ -8,7 +8,7 @@ * Time: 4:09 PM */ @Table(name="persons") -@Cache(maxSize = 10000, maxAge = 1000 * 60 * 60) +@Cache(maxSize = 6, maxAge = 1000 * 60 * 60) public class Person { @Id