diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java index bd74cbd31..74200beb9 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java @@ -842,8 +842,14 @@ public class MappingRepository extends MetaDataRepository { } if (field.isSerialized()) { - if (_dict.maxEmbeddedBlobSize != -1) + if (_dict.maxEmbeddedBlobSize != -1) { + handler = defaultHandler(field, adapting); + if (handler != null) { + if (installHandlers) + field.setHandler(handler); + } return new MaxEmbeddedBlobFieldStrategy(); + } } else { // check for mapped strategy Object strat = mappedStrategy(field, field.getType(), adapting); @@ -859,18 +865,36 @@ public class MappingRepository extends MetaDataRepository { // check for known field strategies if (!field.isSerialized() && (field.getType() == byte[].class || field.getType() == Byte[].class)) { - if (_dict.maxEmbeddedBlobSize != -1) + if (_dict.maxEmbeddedBlobSize != -1) { + handler = defaultHandler(field, adapting); + if (handler != null) { + if (installHandlers) + field.setHandler(handler); + } return new MaxEmbeddedByteArrayFieldStrategy(); + } } else if (!field.isSerialized() && (field.getType() == char[].class || field.getType() == Character[].class)) { - if (_dict.maxEmbeddedClobSize != -1 && isClob(field, false)) + if (_dict.maxEmbeddedClobSize != -1 && isClob(field, false)) { + handler = defaultHandler(field, adapting); + if (handler != null) { + if (installHandlers) + field.setHandler(handler); + } return new MaxEmbeddedCharArrayFieldStrategy(); + } } else if (!field.isSerialized()) { FieldStrategy strat = defaultTypeStrategy(field, installHandlers, adapting); - if (strat != null) + if (strat != null) { + handler = defaultHandler(field, adapting); + if (handler != null) { + if (installHandlers) + field.setHandler(handler); + } return strat; + } } // check for default handler diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java index e01804a9d..993fb1f29 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java @@ -180,7 +180,7 @@ public abstract class EmbedValueHandler if (ecols.length == 0) continue; - cval = (em == null) ? null : em.fetch(i); + cval = (em == null) ? null : getValue(embed, em, i); cval = embed.toEmbeddedDataStoreValue(cval, store); if (cols.length == 1) { // rvals is empty @@ -196,6 +196,13 @@ public abstract class EmbedValueHandler } return idx; } + + private Object getValue(Embeddable embed, OpenJPAStateManager sm, int idx) { + if (embed instanceof MaxEmbeddedLobFieldStrategy) { + return ((MaxEmbeddedLobFieldStrategy)embed).getValue(sm); + } + return sm.fetch(idx); + } /** * Helper to convert a datastore value to its object equivalent. diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java index 25cfdb800..38766fd22 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java @@ -60,11 +60,11 @@ public class HandlerFieldStrategy private static final Localizer _loc = Localizer.forPackage (HandlerFieldStrategy.class); - private Column[] _cols = null; - private ColumnIO _io = null; - private Object[] _args = null; - private boolean _load = false; - private boolean _lob = false; + protected Column[] _cols = null; + protected ColumnIO _io = null; + protected Object[] _args = null; + protected boolean _load = false; + protected boolean _lob = false; public void map(boolean adapt) { if (field.getHandler() == null) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java index bc01583bc..875a38fbc 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java @@ -105,4 +105,13 @@ public class MaxEmbeddedBlobFieldStrategy _maxSize = dict.maxEmbeddedBlobSize; field.setUsesImplData(Boolean.TRUE); } + + protected Object getValue(OpenJPAStateManager sm) { + byte[] b = (byte[]) sm.getImplData(field.getIndex()); + if (b == null || (b.length > _maxSize && !field.getColumns()[0].isNotNull())) + return null; + sm.setImplData(field.getIndex(), null); + DBDictionary.SerializedData dat = new DBDictionary.SerializedData(b); + return dat; + } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java index bdd88cb38..5b22f0f1c 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java @@ -56,9 +56,8 @@ public class MaxEmbeddedByteArrayFieldStrategy protected void update(OpenJPAStateManager sm, Row row) throws SQLException { - byte[] b = PrimitiveWrapperArrays.toByteArray(sm.fetchObject - (field.getIndex())); - if (b == null || (b.length > _maxSize && !field.getColumns()[0].isNotNull())) + byte[] b = (byte[]) getValue(sm); + if (b == null) row.setBytes(field.getColumns()[0], null); else row.setBytes(field.getColumns()[0], b); @@ -94,4 +93,12 @@ public class MaxEmbeddedByteArrayFieldStrategy DBDictionary dict = field.getMappingRepository().getDBDictionary(); _maxSize = dict.maxEmbeddedBlobSize; } + + protected Object getValue(OpenJPAStateManager sm) { + byte[] b = PrimitiveWrapperArrays.toByteArray(sm.fetchObject + (field.getIndex())); + if (b == null || (b.length > _maxSize && !field.getColumns()[0].isNotNull())) + return null; + return b; + } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedCharArrayFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedCharArrayFieldStrategy.java index 87254b463..129d5deaa 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedCharArrayFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedCharArrayFieldStrategy.java @@ -111,4 +111,13 @@ public class MaxEmbeddedCharArrayFieldStrategy DBDictionary dict = field.getMappingRepository().getDBDictionary(); _maxSize = dict.maxEmbeddedClobSize; } + + protected Object getValue(OpenJPAStateManager sm) { + char[] c = PrimitiveWrapperArrays. + toCharArray(sm.fetchObject(field.getIndex())); + if (c == null || c.length > _maxSize) + return null; + else + return c; + } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedClobFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedClobFieldStrategy.java index c81c334d0..1764d1063 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedClobFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedClobFieldStrategy.java @@ -52,8 +52,8 @@ public class MaxEmbeddedClobFieldStrategy protected void update(OpenJPAStateManager sm, Row row) throws SQLException { - String s = sm.fetchString(field.getIndex()); - if (s == null || (s.length() > _maxSize && !field.getColumns()[0].isNotNull())) + String s = (String) getValue(sm); + if (s == null) row.setNull(field.getColumns()[0], true); else row.setString(field.getColumns()[0], s); @@ -81,4 +81,12 @@ public class MaxEmbeddedClobFieldStrategy DBDictionary dict = field.getMappingRepository().getDBDictionary(); _maxSize = dict.maxEmbeddedClobSize; } + + protected Object getValue(OpenJPAStateManager sm) { + String s = sm.fetchString(field.getIndex()); + if (s == null || (s.length() > _maxSize && !field.getColumns()[0].isNotNull())) { + return null; + } + return s; + } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java index cc9d8c7c5..0bc8426ae 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java @@ -46,7 +46,7 @@ import org.apache.openjpa.meta.JavaTypes; * @since 0.4.0 */ abstract class MaxEmbeddedLobFieldStrategy - extends AbstractFieldStrategy { + extends HandlerFieldStrategy { /** * Return the expected type of the field from {@link JavaTypes} or @@ -95,11 +95,13 @@ abstract class MaxEmbeddedLobFieldStrategy tmpCol.setIdentifier(fieldName); tmpCol.setJavaType(getExpectedJavaType()); tmpCol.setSize(-1); - Column[] cols = vinfo.getColumns(field, fieldName, + _cols = vinfo.getColumns(field, fieldName, new Column[]{ tmpCol }, field.getTable(), adapt); - - field.setColumns(cols); - field.setColumnIO(vinfo.getColumnIO()); + _io = vinfo.getColumnIO(); + if (_io == null) + _io = field.getColumnIO(); + field.setColumns(_cols); + field.setColumnIO(_io); field.mapConstraints(fieldName, adapt); field.mapPrimaryKey(adapt); } @@ -266,4 +268,6 @@ abstract class MaxEmbeddedLobFieldStrategy Object prevValue) throws SQLException { } + + protected abstract Object getValue(OpenJPAStateManager sm); } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java index 8f26ba3db..ff97c61de 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java @@ -86,4 +86,8 @@ public class EmbedOwner { public Set getEmbedCollection() { return embedCollection; } + + public void setEmbedCollection(Set embedCollection) { + this.embedCollection = embedCollection; + } } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java index eaed5574f..d35826c1d 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java @@ -19,6 +19,7 @@ package org.apache.openjpa.persistence.jdbc.annotations; import java.sql.Types; +import java.util.HashSet; import java.util.Set; import javax.persistence.EntityManager; @@ -70,6 +71,9 @@ public class TestEJBEmbedded extends SingleEMFTestCase { embed.setBlob("foobar".getBytes()); embed.setOwner(owner); owner.setEmbed(embed); + Set embedVals = new HashSet(); + embedVals.add(embed); + owner.setEmbedCollection(embedVals); em.persist(owner); int pk = owner.getPk(); em.getTransaction().commit();