You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ht...@apache.org on 2012/08/14 16:56:09 UTC
svn commit: r1372913 - in /openjpa/branches/2.0.x:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/
Author: hthomann
Date: Tue Aug 14 14:56:09 2012
New Revision: 1372913
URL: http://svn.apache.org/viewvc?rev=1372913&view=rev
Log:
OPENJPA-1682: Backported to 2.0.x this JIRA and revision 941362 from OPENJPA-1387 since the two issues are related/coupled.
Modified:
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java Tue Aug 14 14:56:09 2012
@@ -25,6 +25,8 @@ import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
@@ -78,11 +80,15 @@ public class Column
private String _comment = null;
private boolean _XML = false;
private boolean _isUni1MFK = false;
+ private Set<Constraint> _constraints = new HashSet<Constraint>();
/**
* Default constructor.
*/
public Column() {
+ for (Constraint c : _constraints) {
+ addConstraint(c);
+ }
}
/**
@@ -886,4 +892,66 @@ public class Column
public void setUni1MFK(boolean isUni1MFK) {
_isUni1MFK = isUni1MFK;
}
+
+ /**
+ * Adds the given constraint to this column.
+ */
+ public void addConstraint(Constraint c) {
+ _constraints.add(c);
+ }
+
+ /**
+ * Removes the given constraint from this column.
+ */
+ public void removeConstraint(Constraint c) {
+ _constraints.remove(c);
+ }
+
+ /**
+ * Affirms if this column has any constraint of given type.
+ */
+ public boolean hasConstraint(Class<? extends Constraint> type) {
+ return !getConstraints(type).isEmpty();
+ }
+
+ /**
+ * Gets all constrains attached this column.
+ */
+ public Set<Constraint> getConstraints() {
+ return _constraints;
+ }
+
+ /**
+ * Gets all constrains of the given type attached to this column.
+ */
+ public <T extends Constraint> Set<T> getConstraints(Class<T> type) {
+ Set<T> result = new HashSet<T>();
+ for (Constraint c : _constraints) {
+ if (c.getClass() == type) {
+ result.add((T)c);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Affirms if any unique constraint is attached to this column.
+ */
+ public boolean isUniqueConstraint() {
+ return hasConstraint(Unique.class);
+ }
+
+ /**
+ * Affirms if any index constraint is attached to this column.
+ */
+ public boolean isIndex() {
+ return hasConstraint(Index.class);
+ }
+
+ /**
+ * Affirms if any foreign key constraint is attached to this column.
+ */
+ public boolean isForeignKey() {
+ return hasConstraint(ForeignKey.class);
+ }
}
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java Tue Aug 14 14:56:09 2012
@@ -573,6 +573,7 @@ public class ForeignKey
if (_joins == null)
_joins = new LinkedHashMap();
_joins.put(local, toPK);
+ local.addConstraint(this);
if (_joinsPK == null)
_joinsPK = new LinkedHashMap();
_joinsPK.put(toPK, local);
@@ -629,6 +630,7 @@ public class ForeignKey
if (_joins != null) {
rem = _joins.remove(col);
+ col.removeConstraint(this);
if (rem != null) {
_locals = null;
_pks = null;
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java Tue Aug 14 14:56:09 2012
@@ -67,6 +67,9 @@ public abstract class LocalConstraint
*/
void remove() {
// remove all columns
+ for (Column c : _cols) {
+ c.removeConstraint(this);
+ }
setColumns(null);
super.remove();
}
@@ -110,6 +113,7 @@ public abstract class LocalConstraint
_colList.add(col);
_cols = null;
+ col.addConstraint(this);
}
/**
@@ -123,6 +127,7 @@ public abstract class LocalConstraint
return false;
if (_colList.remove(col)) {
_cols = null;
+ col.removeConstraint(this);
return true;
}
return false;
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java Tue Aug 14 14:56:09 2012
@@ -54,17 +54,6 @@ public class Unique
}
/**
- * Adds the given column.
- * The added column is set to non-nullable because a unique constraint
- * on the database requires that its constituent columns are NOT NULL.
- * @see Column#setNotNull(boolean)
- */
- public void addColumn(Column col) {
- super.addColumn(col);
- col.setNotNull(true);
- }
-
- /**
* Set the name of the constraint. This method cannot be called if the
* constraint already belongs to a table.
* @deprecated
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java Tue Aug 14 14:56:09 2012
@@ -128,6 +128,7 @@ public class DB2Dictionary
supportsDefaultDeleteAction = false;
supportsAlterTableWithDropColumn = false;
supportsLockingWithOrderClause = true;
+ supportsNullUniqueColumn = false;
supportsNullTableForGetColumns = false;
requiresCastForMathFunctions = true;
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Tue Aug 14 14:56:09 2012
@@ -196,6 +196,7 @@ public class DBDictionary
public boolean supportsRestrictDeleteAction = true;
public boolean supportsCascadeDeleteAction = true;
public boolean supportsNullDeleteAction = true;
+ public boolean supportsNullUniqueColumn = true;
public boolean supportsDefaultDeleteAction = true;
public boolean supportsRestrictUpdateAction = true;
public boolean supportsCascadeUpdateAction = true;
@@ -1303,8 +1304,12 @@ public class DBDictionary
if (col != null && (col.getType() == Types.CLOB
|| col.getType() == Types.LONGVARCHAR))
setClobString(stmnt, idx, (String) val, col);
- else
- setString(stmnt, idx, (String) val, col);
+ else {
+ if (val instanceof String)
+ setString(stmnt, idx, (String) val, col);
+ else
+ setString(stmnt, idx, val.toString(), col);
+ }
break;
case JavaTypes.OBJECT:
setBlobObject(stmnt, idx, val, col, store);
@@ -3589,7 +3594,7 @@ public class DBDictionary
if (!alter) {
if (col.getDefaultString() != null && !col.isAutoAssigned())
buf.append(" DEFAULT ").append(col.getDefaultString());
- if (col.isNotNull())
+ if (col.isNotNull() || (!supportsNullUniqueColumn && col.hasConstraint(Unique.class)))
buf.append(" NOT NULL");
}
if (col.isAutoAssigned()) {
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java Tue Aug 14 14:56:09 2012
@@ -68,6 +68,7 @@ public class DerbyDictionary
supportsSimpleCaseExpression = false;
supportsComments = true;
+ supportsNullUniqueColumn = false;
fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
"BIGINT", "INTEGER",
Modified: openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java (original)
+++ openjpa/branches/2.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java Tue Aug 14 14:56:09 2012
@@ -690,8 +690,6 @@ public class RowImpl
&& col.getDefaultString() != null)
return;
}
- if (val == null && col.isNotNull())
- val = JavaSQLTypes.getEmptyValue(col.getJavaType());
flush(col, val, metaType, true);
}
Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java (original)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java Tue Aug 14 14:56:09 2012
@@ -23,6 +23,8 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
/**
@@ -32,6 +34,7 @@ import javax.persistence.Version;
*
*/
@Entity
+@Table(uniqueConstraints=@UniqueConstraint(columnNames={"UNS"}))
public class NullValues {
@Id
@GeneratedValue
@@ -61,6 +64,9 @@ public class NullValues {
@Basic(optional=false)
private BlobValue notOptionalBlob;
+ @Column(name="UNS")
+ private String uniqueNullable;
+
@Version
private int version;
@@ -78,6 +84,7 @@ public class NullValues {
setNotNullableBlob(new BlobValue());
setOptionalBlob(new BlobValue());
setNotOptionalBlob(new BlobValue());
+ setUniqueNullable("");
}
public long getId() {
@@ -148,6 +155,14 @@ public class NullValues {
this.notOptionalBlob = notOptionalBlob;
}
+ public String getUniqueNullable() {
+ return uniqueNullable;
+ }
+
+ public void setUniqueNullable(String s) {
+ uniqueNullable = s;
+ }
+
public int getVersion() {
return version;
}
Modified: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java?rev=1372913&r1=1372912&r2=1372913&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java (original)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java Tue Aug 14 14:56:09 2012
@@ -18,8 +18,16 @@
*/
package org.apache.openjpa.persistence.nullity;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
import javax.persistence.RollbackException;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.OracleDictionary;
+import org.apache.openjpa.jdbc.sql.SybaseDictionary;
import org.apache.openjpa.persistence.InvalidStateException;
import org.apache.openjpa.persistence.OpenJPAPersistence;
@@ -33,8 +41,10 @@ import org.apache.openjpa.persistence.Op
*/
public class TestBasicFieldNullity extends AbstractNullityTestCase {
+ private DBDictionary dict = null;
public void setUp() {
setUp(CLEAR_TABLES, NullValues.class);
+ dict = ((JDBCConfiguration)emf.getConfiguration()).getDBDictionaryInstance();
}
public void testNullOnOptionalFieldIsAllowed() {
@@ -113,5 +123,65 @@ public class TestBasicFieldNullity exten
pc.setNotNullableBlob(null);
assertCommitFails(pc, !NEW, RollbackException.class);
}
+
+ public void testUniqueStringColumnCanBeNull() {
+ if (!isUniqueColumnNullable()) {
+ return;
+ }
+ NullValues pc = new NullValues();
+ pc.setUniqueNullable(null);
+ assertCommitSucceeds(pc, NEW);
+ }
+
+ public void testUniqueStringColumnAsNull() {
+ if (!isUniqueColumnNullable()) {
+ return;
+ }
+ NullValues pc = new NullValues();
+ pc.setUniqueNullable(null);
+ assertCommitSucceeds(pc, NEW);
+
+ String jpql = "select n from NullValues n where n.uniqueNullable = :p";
+ EntityManager em = emf.createEntityManager();
+ List<NullValues> result = em.createQuery(jpql)
+ .setParameter("p", null)
+ .getResultList();
+ assertFalse(result.isEmpty());
+ for (NullValues n : result)
+ assertNull(n.getUniqueNullable());
+ }
+
+ public void testUniqueStringColumnAsEmpty() {
+ String EMPTY_STRING = "";
+ NullValues pc = new NullValues();
+ pc.setUniqueNullable(EMPTY_STRING);
+ assertCommitSucceeds(pc, NEW);
+
+ String jpql = "select n from NullValues n where n.uniqueNullable = :p";
+ if (dict instanceof OracleDictionary)
+ jpql = "select n from NullValues n where n.uniqueNullable IS NULL";
+ EntityManager em = emf.createEntityManager();
+ Query query = em.createQuery(jpql);
+ if (!(dict instanceof OracleDictionary))
+ query.setParameter("p", EMPTY_STRING);
+ List<NullValues> result = query.getResultList();
+ assertFalse(result.isEmpty());
+ for (NullValues n : result) {
+ if (dict instanceof OracleDictionary) {
+ assertNull(n.getUniqueNullable());
+ }
+ else if (dict instanceof SybaseDictionary) {
+ // Sybase converts empty strings to ""
+ assertEquals(" ", n.getUniqueNullable());
+ }
+ else {
+ assertEquals(EMPTY_STRING, n.getUniqueNullable());
+ }
+ }
+ }
+
+ boolean isUniqueColumnNullable() {
+ return ((JDBCConfiguration)emf.getConfiguration()).getDBDictionaryInstance().supportsNullUniqueColumn;
+ }
}