Author: ppoddar
Date: Wed Jun 18 16:25:59 2008
New Revision: 669332
URL: http://svn.apache.org/viewvc?rev=669332&view=rev
Log:
OPENJPA-533: Update query can set single-valued association to NULL or non-NULL.
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Null.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Null.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Null.java?rev=669332&r1=669331&r2=669332&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Null.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Null.java
Wed Jun 18 16:25:59 2008
@@ -26,7 +26,7 @@
*
* @author Abe White
*/
-class Null
+public class Null
extends Const {
public Class getType() {
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=669332&r1=669331&r2=669332&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
Wed Jun 18 16:25:59 2008
@@ -71,6 +71,7 @@
import org.apache.openjpa.jdbc.kernel.exps.ExpContext;
import org.apache.openjpa.jdbc.kernel.exps.ExpState;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
+import org.apache.openjpa.jdbc.kernel.exps.Null;
import org.apache.openjpa.jdbc.kernel.exps.Val;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
@@ -2047,7 +2048,8 @@
augmentUpdates = false;
Val val = (Val) next.getValue();
-
+ if (val == null)
+ val = new Null();
Column col = fmd.getColumns()[0];
if (allowAlias) {
sql.append(sel.getColumnAlias(col));
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=669332&r1=669331&r2=669332&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
Wed Jun 18 16:25:59 2008
@@ -483,7 +483,9 @@
JPQLNode[] nodes = root().findChildrenByID(JJTUPDATEITEM);
for (int i = 0; nodes != null && i < nodes.length; i++) {
Path path = getPath(firstChild(nodes[i]));
- Value val = getValue(onlyChild(lastChild(nodes[i])));
+ JPQLNode lastChild = lastChild(nodes[i]);
+ Value val = (lastChild.children == null)
+ ? null : getValue(onlyChild(lastChild));
exps.putUpdate(path, val);
}
}
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java?rev=669332&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java
Wed Jun 18 16:25:59 2008
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.jdbc.query.domain.Application;
+import org.apache.openjpa.persistence.jdbc.query.domain.Applicant;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests that update query can set single-valued association field to non-null
+ * or null values.
+ *
+ * Originally reported in
+ * <A HRE="http://issues.apache.org/jira/browse/OPENJPA-533>OPENJPA-533</A>
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class TestUpdateSingleValuedAssociation extends SingleEMFTestCase {
+ private static boolean MUST_BE_NULL = true;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp(CLEAR_TABLES, Application.class, Applicant.class);
+ }
+
+ public void testUpdateSingleValuedAssociationToNullViaParameter() {
+ createApplicationWithNonNullApplicant();
+ assertUserNullity(!MUST_BE_NULL);
+
+ String jpql = "UPDATE Application a SET a.user = :user";
+ updateByQuery(jpql, "user", null);
+
+ assertUserNullity(MUST_BE_NULL);
+ }
+
+ public void testUpdateSingleValuedAssociationToNullViaLiteral() {
+ createApplicationWithNonNullApplicant();
+ assertUserNullity(!MUST_BE_NULL);
+
+ String jpql = "UPDATE Application a SET a.user = NULL";
+ updateByQuery(jpql);
+
+ assertUserNullity(MUST_BE_NULL);
+ }
+
+ public void testUpdateSingleValuedAssociationToNonNullViaParameter() {
+ Application pc = createApplicationWithNullApplicant();
+ assertNull(pc.getUser());
+
+ String jpql = "UPDATE Application a SET a.user = :user";
+ Applicant newUser = createApplicant();
+ updateByQuery(jpql, "user", newUser);
+
+ assertUserNullity(!MUST_BE_NULL);
+ }
+
+ void assertUserNullity(boolean shouldBeNull) {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ List<Application> result =
+ em.createQuery("SELECT a FROM Application
a").getResultList();
+ assertFalse(result.isEmpty());
+ for (Application pc : result) {
+ Applicant user = pc.getUser();
+ if (shouldBeNull)
+ assertNull(user);
+ else
+ assertNotNull(user);
+ }
+ em.getTransaction().rollback();
+ }
+
+ Application createApplicationWithNonNullApplicant() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Application app = new Application();
+ Applicant user = new Applicant();
+ user.setName("Non-Null User");
+ app.setUser(user);
+ em.persist(app);
+ em.persist(user);
+ em.getTransaction().commit();
+ return app;
+ }
+
+ Application createApplicationWithNullApplicant() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Application app = new Application();
+ em.persist(app);
+ em.getTransaction().commit();
+ return app;
+ }
+
+ Applicant createApplicant() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Applicant user = new Applicant();
+ user.setName("Non-Null User");
+ em.persist(user);
+ em.getTransaction().commit();
+ return user;
+ }
+
+ public void updateByQuery(String jpql, Object...params) {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Query query = em.createQuery(jpql);
+ for (int i=0; params != null && i<params.length; i=+2) {
+ query.setParameter(params[i].toString(), params[i+1]);
+ }
+ query.executeUpdate();
+ em.getTransaction().commit();
+ }
+}
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java?rev=669332&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java
Wed Jun 18 16:25:59 2008
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.*;
+
+/**
+ * Simple persistent entity as a target of uni-directional one-to-one
+ * association.
+ *
+ * @author Pinaki Poddar
+ *
+ */
[EMAIL PROTECTED]
+public class Applicant {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+}
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java?rev=669332&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java
Wed Jun 18 16:25:59 2008
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+
+/**
+ * Simple persistent entity as a source of uni-directional one-to-one
+ * association.
+ *
+ * @author Pinaki Poddar
+ *
+ */
[EMAIL PROTECTED]
+public class Application {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ @ManyToOne
+ @JoinColumn(nullable = true)
+ @ForeignKey(deleteAction = ForeignKeyAction.NULL)
+ private Applicant user;
+
+ public Applicant getUser() {
+ return user;
+ }
+
+ public void setUser(Applicant user) {
+ this.user = user;
+ }
+
+ public long getId() {
+ return id;
+ }
+}