OPENJPA-1306 - Add basic extended lock scope support, 3 junit testing basic, secondary table, join table, inheritance entity, element collections (lazy/eager), 1x1 (lazy/eager) and 1xm (lazy/eager).

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@831194 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Albert Lee 2009-10-30 04:09:05 +00:00
parent d0cf5b404e
commit 8c8636fce9
33 changed files with 5675 additions and 18 deletions

View File

@ -401,6 +401,23 @@ public class DelegatingFetchConfiguration
} }
} }
public int getLockScope() {
try {
return _fetch.getLockScope();
} catch (RuntimeException re) {
throw translate(re);
}
}
public FetchConfiguration setLockScope(int scope) {
try {
_fetch.setLockScope(scope);
return this;
} catch (RuntimeException re) {
throw translate(re);
}
}
public int getReadLockLevel() { public int getReadLockLevel() {
try { try {
return _fetch.getReadLockLevel(); return _fetch.getReadLockLevel();

View File

@ -36,7 +36,7 @@ import org.apache.openjpa.meta.FieldMetaData;
* @author Pinaki Poddar * @author Pinaki Poddar
*/ */
public interface FetchConfiguration public interface FetchConfiguration
extends Serializable, Cloneable, LockLevels, QueryFlushModes { extends Serializable, Cloneable, LockLevels, LockScopes, QueryFlushModes {
/** /**
* Constant to revert any setting back to its default value. * Constant to revert any setting back to its default value.
@ -268,7 +268,21 @@ public interface FetchConfiguration
* @since 0.3.1 * @since 0.3.1
*/ */
public FetchConfiguration setLockTimeout(int timeout); public FetchConfiguration setLockTimeout(int timeout);
/**
* The lock scope for next fetch.
*
* @since 2.0.0
*/
public int getLockScope();
/**
* The lock scope for next fetch.
*
* @since 2.0.0
*/
public FetchConfiguration setLockScope(int scope);
/** /**
* The number of milliseconds to wait for a query, or -1 for no * The number of milliseconds to wait for a query, or -1 for no
* limit. * limit.

View File

@ -78,7 +78,7 @@ public class FetchConfigurationImpl
public int flushQuery = 0; public int flushQuery = 0;
public int lockTimeout = -1; public int lockTimeout = -1;
public int queryTimeout = -1; public int queryTimeout = -1;
public int lockMode = 0; public int lockScope = LOCKSCOPE_NORMAL;
public int readLockLevel = LOCK_NONE; public int readLockLevel = LOCK_NONE;
public int writeLockLevel = LOCK_NONE; public int writeLockLevel = LOCK_NONE;
public Set<String> fetchGroups = null; public Set<String> fetchGroups = null;
@ -168,6 +168,7 @@ public class FetchConfigurationImpl
setExtendedPathLookup(fetch.getExtendedPathLookup()); setExtendedPathLookup(fetch.getExtendedPathLookup());
setLockTimeout(fetch.getLockTimeout()); setLockTimeout(fetch.getLockTimeout());
setQueryTimeout(fetch.getQueryTimeout()); setQueryTimeout(fetch.getQueryTimeout());
setLockScope(fetch.getLockScope());
clearFetchGroups(); clearFetchGroups();
addFetchGroups(fetch.getFetchGroups()); addFetchGroups(fetch.getFetchGroups());
clearFields(); clearFields();
@ -482,6 +483,22 @@ public class FetchConfigurationImpl
return this; return this;
} }
public int getLockScope() {
return _state.lockScope;
}
public FetchConfiguration setLockScope(int scope) {
if (scope != DEFAULT
&& scope != LockScopes.LOCKSCOPE_NORMAL
&& scope != LockScopes.LOCKSCOPE_EXTENDED)
throw new IllegalArgumentException(_loc.get(
"bad-lock-scope", new Integer(scope)).getMessage());
if (scope == DEFAULT )
_state.lockScope = LOCKSCOPE_NORMAL;
else
_state.lockScope = scope;
return this;
}
public int getReadLockLevel() { public int getReadLockLevel() {
String lockModeKey = "openjpa.FetchPlan.ReadLockMode"; String lockModeKey = "openjpa.FetchPlan.ReadLockMode";

View File

@ -0,0 +1,39 @@
/*
* 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.kernel;
/**
* Defines lock scope levels used for MixedLockManager.
*
* @since 2.0.0
*/
public interface LockScopes {
/**
* Generic Normal lock scope level. Value of 0.
*
*/
public static final int LOCKSCOPE_NORMAL = 0;
/**
* Generic extended lock scope level. Value of 10.
*/
public static final int LOCKSCOPE_EXTENDED = 10;
}

View File

@ -448,4 +448,5 @@ fill-factory-error: Error while fill data with factory strategy. The error \
occurred while invoking "{0}" with key "{1}" and value "{2}" of type "{3}". \ occurred while invoking "{0}" with key "{1}" and value "{2}" of type "{3}". \
See nested exception for details. See nested exception for details.
writebehind-cfg-err: Missing required WriteBehind configuration parameter "{0}" writebehind-cfg-err: Missing required WriteBehind configuration parameter "{0}"
bad-lock-scope: This lock manager does not recognize lock scope "{0}".

View File

@ -0,0 +1,113 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1x1LfNormal"
, query="SELECT c FROM LSE1x1Lf c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1x1LfExtended"
, query="SELECT c FROM LSE1x1Lf c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1x1Lf implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@OneToOne
private LSE1x1Rt uniRight;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public LSE1x1Rt getUniRight() {
return uniRight;
}
public void setUniRight(LSE1x1Rt uniRight) {
this.uniRight = uniRight;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(this)) + "[id=" + getId()
+ ", ver=" + getVersion() + ", firstName=" + firstName + "]"
+ " uniRight=" + getUniRight()
;
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRight = (LSE1x1Rt) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRight);
}
}

View File

@ -0,0 +1,115 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1x1LfJTNormal"
, query="SELECT c FROM LSE1x1LfJT c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1x1LfJTExtended"
, query="SELECT c FROM LSE1x1LfJT c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1x1LfJT implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@OneToOne
@JoinTable(name="Uni1x1LfJT_Uni1x1RT")
private LSE1x1Rt uniRightJT;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public LSE1x1Rt getUniRightJT() {
return uniRightJT;
}
public void setUniRightJT(LSE1x1Rt uniRightJT) {
this.uniRightJT = uniRightJT;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(this)) + "[id=" + getId()
+ ", ver=" + getVersion() + ", firstName=" + firstName + "]"
+ " uniRightJT=" + getUniRightJT()
;
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRightJT = (LSE1x1Rt) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRightJT);
}
}

View File

@ -0,0 +1,116 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1x1LfJTLzyNormal"
, query="SELECT c FROM LSE1x1LfJTLzy c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1x1LfJTLzyExtended"
, query="SELECT c FROM LSE1x1LfJTLzy c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1x1LfJTLzy implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@OneToOne(fetch=FetchType.LAZY)
@JoinTable(name="Uni1x1LfJT_Uni1x1RT")
private LSE1x1Rt uniRightJT;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public LSE1x1Rt getUniRightJT() {
return uniRightJT;
}
public void setUniRightJT(LSE1x1Rt uniRightJT) {
this.uniRightJT = uniRightJT;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(this)) + "[id=" + getId()
+ ", ver=" + getVersion() + ", firstName=" + firstName + "]"
+ " uniRightJT=" + getUniRightJT()
;
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRightJT = (LSE1x1Rt) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRightJT);
}
}

View File

@ -0,0 +1,114 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1x1LfLzyNormal"
, query="SELECT c FROM LSE1x1LfLzy c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1x1LfLzyExtended"
, query="SELECT c FROM LSE1x1LfLzy c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1x1LfLzy implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@OneToOne(fetch=FetchType.LAZY)
private LSE1x1Rt uniRight;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public LSE1x1Rt getUniRight() {
return uniRight;
}
public void setUniRight(LSE1x1Rt uniRight) {
this.uniRight = uniRight;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(this)) + "[id=" + getId()
+ ", ver=" + getVersion() + ", firstName=" + firstName + "]"
+ " uniRight=" + getUniRight()
;
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRight = (LSE1x1Rt) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRight);
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
@Entity
public class LSE1x1Rt implements Externalizable {
@Id
private int id;
@Version
private int version;
private String lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", lastName=" + lastName + "]";
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
lastName = in.readUTF();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(lastName);
}
}

View File

@ -0,0 +1,118 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.HashSet;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1xmLfNormal"
, query="SELECT c FROM LSE1xmLf c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1xmLfExtended"
, query="SELECT c FROM LSE1xmLf c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1xmLf implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@OneToMany // (cascade=CascadeType.ALL) (mappedBy="ownerOne")
private Collection<LSE1xmRt> uniRight = new HashSet<LSE1xmRt>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Collection<LSE1xmRt> getUniRight() {
return uniRight;
}
public void setUnitRight(Collection<LSE1xmRt> uniRight) {
this.uniRight = uniRight;
}
public void addUnitRight(LSE1xmRt uniRight) {
this.uniRight.add(uniRight);
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", firstName=" + firstName + "] ownedMany=" + getUniRight();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRight = (Collection<LSE1xmRt>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRight);
}
}

View File

@ -0,0 +1,119 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.HashSet;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1xmLfEgrNormal"
, query="SELECT c FROM LSE1xmLfEgr c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1xmLfEgrExtended"
, query="SELECT c FROM LSE1xmLfEgr c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1xmLfEgr implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@OneToMany(fetch=FetchType.EAGER) //(mappedBy="ownerOne")
private Collection<LSE1xmRt> uniRight = new HashSet<LSE1xmRt>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Collection<LSE1xmRt> getUniRight() {
return uniRight;
}
public void setUnitRight(Collection<LSE1xmRt> uniRight) {
this.uniRight = uniRight;
}
public void addUnitRight(LSE1xmRt uniRight) {
this.uniRight.add(uniRight);
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", firstName=" + firstName + "] ownedMany=" + getUniRight();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRight = (Collection<LSE1xmRt>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRight);
}
}

View File

@ -0,0 +1,120 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.HashSet;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1xmLfJTNormal"
, query="SELECT c FROM LSE1xmLfJT c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1xmLfJTExtended"
, query="SELECT c FROM LSE1xmLfJT c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1xmLfJT implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@JoinTable
@OneToMany //(mappedBy="ownerOne")
private Collection<LSE1xmRt> uniRight = new HashSet<LSE1xmRt>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Collection<LSE1xmRt> getUniRight() {
return uniRight;
}
public void setUnitRight(Collection<LSE1xmRt> uniRight) {
this.uniRight = uniRight;
}
public void addUnitRight(LSE1xmRt uniRight) {
this.uniRight.add(uniRight);
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", firstName=" + firstName + "] ownedMany=" + getUniRight();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRight = (Collection<LSE1xmRt>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRight);
}
}

View File

@ -0,0 +1,119 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.HashSet;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSE1xmLfJTEgrNormal"
, query="SELECT c FROM LSE1xmLfJTEgr c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSE1xmLfJTEgrExtended"
, query="SELECT c FROM LSE1xmLfJTEgr c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSE1xmLfJTEgr implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@OneToMany(fetch=FetchType.EAGER)//(mappedBy="ownerOne")
private Collection<LSE1xmRt> uniRight = new HashSet<LSE1xmRt>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Collection<LSE1xmRt> getUniRight() {
return uniRight;
}
public void setUnitRight(Collection<LSE1xmRt> uniRight) {
this.uniRight = uniRight;
}
public void addUnitRight(LSE1xmRt uniRight) {
this.uniRight.add(uniRight);
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", firstName=" + firstName + "] ownedMany=" + getUniRight();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
uniRight = (Collection<LSE1xmRt>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(uniRight);
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
@Entity
public class LSE1xmRt implements Externalizable {
@Id
private int id;
@Version
private int version;
private String lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", lastName=" + lastName + "]";
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
lastName = in.readUTF();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(lastName);
}
}

View File

@ -0,0 +1,110 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSEBaseNormal"
, query="SELECT c FROM LSEBase c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSEBaseExtended"
, query="SELECT c FROM LSEBase c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSEBase implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
private String lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + "] first=" + getFirstName()
+ ", last=" + getLastName();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = (String) in.readObject();
lastName = (String) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeObject(firstName);
out.writeObject(lastName);
}
}

View File

@ -0,0 +1,118 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSEEleColNormal"
, query="SELECT c FROM LSEEleCol c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSEEleColExtended"
, query="SELECT c FROM LSEEleCol c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSEEleCol implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@ElementCollection
protected Set<String> collection = new HashSet<String>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String name) {
this.firstName = name;
}
public Set<String> getCollection() {
return collection;
}
public void setCollection(Set<String> collection) {
this.collection = collection;
}
public void addCollection(String element) {
collection.add(element);
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", firstName=" + getFirstName() + "] one=" + getCollection();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
collection = (Set<String>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(collection);
}
}

View File

@ -0,0 +1,119 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSEEleColEgrNormal"
, query="SELECT c FROM LSEEleColEgr c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSEEleColEgrExtended"
, query="SELECT c FROM LSEEleColEgr c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSEEleColEgr implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@ElementCollection(fetch=FetchType.EAGER)
protected Set<String> collection = new HashSet<String>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String name) {
this.firstName = name;
}
public Set<String> getCollection() {
return collection;
}
public void setCollection(Set<String> collection) {
this.collection = collection;
}
public void addCollection(String element) {
collection.add(element);
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + ", firstName=" + getFirstName() + "] one=" + getCollection();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = in.readUTF();
collection = (Set<String>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeUTF(firstName);
out.writeObject(collection);
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Version;
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class LSEJoinAbs implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + "] first=" + getFirstName();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = (String) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeObject(firstName);
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
@NamedQueries ( value={
@NamedQuery(
name="findLSEJoinConNormal"
, query="SELECT c FROM LSEJoinCon c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSEJoinConExtended"
, query="SELECT c FROM LSEJoinCon c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSEJoinCon extends LSEJoinAbs implements Externalizable {
private String lastName;
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + super.toString()
+ ", last=" + getLastName();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
super.readExternal(in);
lastName = (String) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeObject(lastName);
}
}

View File

@ -0,0 +1,112 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.SecondaryTable;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSESecTblNormal"
, query="SELECT c FROM LSESecTbl c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSESecTblExtended"
, query="SELECT c FROM LSESecTbl c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
@SecondaryTable(name="LSESecTblDtl")
public class LSESecTbl implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
@Column(table="LSESecTblDtl")
private String lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(this)) + "[id=" + getId()
+ ", ver=" + getVersion() + "] first=" + getFirstName() + ", last=" + getLastName();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = (String) in.readObject();
lastName = (String) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeObject(firstName);
out.writeObject(lastName);
}
}

View File

@ -0,0 +1,100 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.Version;
@NamedQueries ( value={
@NamedQuery(
name="findLSESngTblAbsNormal"
, query="SELECT c FROM LSESngTblAbs c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSESngTblAbsExtended"
, query="SELECT c FROM LSESngTblAbs c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class LSESngTblAbs implements Externalizable {
@Id
private int id;
@Version
private int version;
private String firstName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public int getVersion() {
return version;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
+ getId() + ", ver=" + getVersion() + "] first=" + getFirstName();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
id = in.readInt();
version = in.readInt();
firstName = (String) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeInt(version);
out.writeObject(firstName);
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.lock.extended;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.LockModeType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
@NamedQueries ( value={
@NamedQuery(
name="findLSESngTblConNormal"
, query="SELECT c FROM LSESngTblCon c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
),
@NamedQuery(
name="findLSESngTblConExtended"
, query="SELECT c FROM LSESngTblCon c WHERE c.firstName LIKE :firstName"
, lockMode=LockModeType.PESSIMISTIC_WRITE
, hints={@QueryHint(name="javax.persistence.lock.scope",value="EXTENDED")}
)
}
)
@Entity
public class LSESngTblCon extends LSESngTblAbs implements Externalizable {
private String lastName;
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String toString() {
return this.getClass().getName() + '@'
+ Integer.toHexString(System.identityHashCode(this)) + super.toString()
+ ", last=" + getLastName();
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
super.readExternal(in);
lastName = (String) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeObject(lastName);
}
}

View File

@ -0,0 +1,324 @@
/*
* 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.lock.extended;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PessimisticLockScope;
import javax.persistence.Query;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.persistence.MixedLockLevelsHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
/**
* Base class for locking extended scope tests.
*
* Test JPA 2.0 EM interface normal lock scope behaviors with "mixed" lock
* manager. When an entity instance is locked using pessimistic locking, the
* persistence provider must lock the database row(s) that correspond to the
* non-collection-valued persistent state of that instance. If a joined
* inheritance strategy is used, or if the entity is otherwise mapped to a
* secondary table, this entails locking the row(s) for the entity instance in
* the additional table(s). Entity relationships for which the locked entity
* contains the foreign key will also be locked, but not the state of the
* referenced entities (unless hose entities are explicitly locked). Element
* collections and relationships for which the entity does not contain the
* foreign key (such as relationships that are mapped to join tables or
* unidirectional one-to-many relationships for which the target entity contains
* the foreign key) will not be locked by default.
*
* Element collections and relationships owned by the entity that are contained
* in join tables will be locked if the javax.persistence.lock.scope property is
* specified with a value of PessimisticLockScope.EXTENDED. The state of
* entities referenced by such relationships will not be locked (unless those
* entities are explicitly locked). This property may be passed as an argument
* to the methods of the EntityManager and Query interfaces that allow lock
* modes to be specified or used with the NamedQuery annotation.
*
* @since 2.0
*/
public abstract class LockScopeTestCase extends SQLListenerTestCase {
protected final String Select = "SELECT.*FROM.*";
protected final String Where = ".*WHERE.*";
protected final String ForUpdateRex = "FOR UPDATE.*";
protected final String ForUpdateClause = "(" + ForUpdateRex + ")";
protected final String ForUpdate = ForUpdateClause + "{1}";
protected final String NoForUpdate = ForUpdateClause + "{0}";
protected final String DB2LockClause = "(" + ForUpdateRex +
"|FOR READ ONLY WITH R. USE AND KEEP (UPDATE|EXCLUSIVE) LOCKS)";
protected final String DB2Lock = DB2LockClause + "{1}";
protected final String NoDB2Lock = DB2LockClause + "{0}";
protected List<String> empTableName = new ArrayList<String>();;
protected Map<String, Object> normalProps;
protected Map<String, Object> extendedProps;
protected void commonSetUp(Class<?>... eClasses ) {
normalProps = new HashMap<String, Object>();
extendedProps = new HashMap<String, Object>();
extendedProps.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED);
for( Class<?> eClazz : eClasses) {
empTableName.add(getMapping(eClazz).getTable().getFullName());
}
cleanupDB();
}
private void cleanupDB() {
EntityManager em = null;
try {
em = emf.createEntityManager();
em.getTransaction().begin();
for (String tableName : empTableName.toArray(new String[empTableName.size()])) {
em.createQuery("delete from " + tableName).executeUpdate();
}
em.getTransaction().commit();
} catch(Exception e) {
e.printStackTrace();
} finally {
if (em != null && em.isOpen()) {
em.close();
}
}
}
protected enum DBType {
access, db2, derby, empress, foxpro, h2, hsql, informix, ingres, jdatastore, mysql, oracle, pointbase, postgres,
sqlserver, sybase
};
protected DBType getDBType(EntityManager em) {
JDBCConfigurationImpl conf = (JDBCConfigurationImpl) getConfiguration(em);
String dictClassName = getConfiguration(em).getDBDictionaryInstance().getClass().getName();
String db = conf.dbdictionaryPlugin.alias(dictClassName);
return DBType.valueOf(db);
}
@SuppressWarnings( { "unused", "deprecation" })
protected JDBCConfiguration getConfiguration(EntityManager em) {
return ((JDBCConfiguration) ((OpenJPAEntityManager) em).getConfiguration());
}
protected Log getLog() {
return emf.getConfiguration().getLog("Tests");
}
protected Log getDumpStackLog() {
return emf.getConfiguration().getLog("DumpStack");
}
/*
* Set Log=LockTestSQL=TRACE to dump the SQL caught by the SQL listener but do not perform SQL assertion.
*/
protected Log getDumpSQLLog() {
return emf.getConfiguration().getLog("LockTestSQL");
}
public void assertLockTestSQLs(String... expected) {
Log log = getDumpSQLLog();
if( log.isTraceEnabled()) {
log.trace("\r\n" + toString(sql));
return;
}
assertAnySQLAnyOrder(expected);
}
protected void logStack(Throwable t) {
StringWriter str = new StringWriter();
PrintWriter print = new PrintWriter(str);
t.printStackTrace(print);
getDumpStackLog().trace(str.toString());
}
// Id designation-
// for basic test:
// [basic=0,sectable=1,singletable=2,join=4,eleColl=5,eleCollEager=6][normal=0|extended=1][entity#]
// For 1x1/1xm tests:
// [1x1=1,1xM=2] [uni=1|bi=2] [left=1|right=2] [normal=1|join=2] [default=0|lazy=1|eager=2]
// [normal=0|extended=1] [n-th entity]
protected <T> void commonLockTest(String testName, Class<T> type, int id0, boolean extended, String queryString,
String namedQueryString, AssertCallback verify) {
getLog().info("** " + testName + "()");
String entityName = type.getName();
String scope = extended ? "Extended" : "Normal";
Map<String, Object> props = extended ? extendedProps : normalProps;
int id1 = id0 + 1;
EntityManager em = null;
T e0 = null;
T e1 = null;
try {
getLog().info("-- Test find with no lock in " + scope + " scope");
em = emf.createEntityManager();
getLog().info(" *Begin a transaction.");
em.getTransaction().begin();
resetSQL();
getLog().info(" *Find " + entityName + "(" + id0 + ") with no lock");
e0 = em.find(type, id0, props);
getLog().info(" *" + (e0 != null ? "F" : "Can not f") + "ind entity");
verify.findNoLockDbSQL(em);
getLog().info(" *Found entity:" + e0);
assertNotNull(" *Found " + entityName + "(" + id0 + ")", e0);
assertEquals(" *Assert no lock applied", LockModeType.NONE, em.getLockMode(e0));
getLog().info(" *Find " + entityName + "(" + id1 + ") with pessimistic force increment lock");
resetSQL();
e1 = em.find(type, id1, LockModeType.PESSIMISTIC_FORCE_INCREMENT, props);
getLog().info(" *" + (e1 != null ? "F" : "Can not f") + "ind entity");
verify.findPessimisticForcIncDbSQL(em);
getLog().info(" *Found entity:" + e1);
assertNotNull(" *Found " + entityName + "(" + id1 + ")", e1);
assertEquals(" *Assert pessimistic force increment lock applied", LockModeType.PESSIMISTIC_FORCE_INCREMENT,
em.getLockMode(e1));
getLog().info("Committing transaction.");
em.getTransaction().commit();
} finally {
em = null;
e0 = e1 = null;
if (em != null && em.isOpen()) {
em.close();
}
}
try {
getLog().info("-- Test query with pessimistic read lock in " + scope + " scope");
em = emf.createEntityManager();
getLog().info(" *Begin a transaction.");
em.getTransaction().begin();
resetSQL();
int beforeReadLevel = getConfiguration(em).getReadLockLevelConstant();
LockModeType beforeReadMode = MixedLockLevelsHelper.fromLockLevel(beforeReadLevel);
getLog().info(" *Save ReadLockLevel before Query:" + beforeReadMode);
getLog().info(" *Query " + entityName + "(" + id0 + ") with PESSIMISTIC_READ lock");
Query q = em.createQuery(queryString);
if (extended) {
q = q.setHint("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED);
}
q = q.setLockMode(LockModeType.PESSIMISTIC_READ);
q = q.setParameter("firstName", "firstName%" + id0);
List<T> es = q.getResultList();
getLog().info(" *Found " + es.size() + " entity");
assertEquals(" *Should find 1 entity", es.size(), 1);
verify.queryPessimisticReadDbSQL(em);
e0 = es.get(0);
getLog().info(" *Found entity:" + e0);
assertNotNull(" *Found " + entityName + "(" + id0 + ")", e0);
assertEquals("Assert pessimistic read lock applied", LockModeType.PESSIMISTIC_READ, em.getLockMode(e0));
assertEquals(" *Read lock should still be " + beforeReadMode + "after query set lock mode",
beforeReadLevel, getConfiguration(em).getReadLockLevelConstant());
getLog().info(
" *Find " + entityName + "(" + id1
+ ") with no lock to verify query lock set does not affect em lock mode.");
resetSQL();
e1 = em.find(type, id1);
getLog().info(" *" + (e1 != null ? "F" : "Can not f") + "ind entity");
verify.findNoLockAfterQueryPessimisticReadDbSQL(em);
getLog().info(" *Found entity:" + e1);
assertNotNull(" *Found " + entityName + "(" + id1 + ")", e1);
assertEquals(" *Assert default lock applied", LockModeType.NONE, em.getLockMode(e1));
getLog().info("Committing transaction.");
em.getTransaction().commit();
} finally {
em = null;
e0 = e1 = null;
if (em != null && em.isOpen()) {
em.close();
}
}
try {
getLog().info("-- Test name query with pessimistic write lock in " + scope + " scope");
em = emf.createEntityManager();
getLog().info(" *Begin a transaction.");
em.getTransaction().begin();
resetSQL();
int beforeReadLevel = getConfiguration(em).getReadLockLevelConstant();
LockModeType beforeReadMode = MixedLockLevelsHelper.fromLockLevel(beforeReadLevel);
getLog().info(" *Save ReadLockLevel before Query:" + beforeReadMode);
getLog().info(" *Query " + entityName + "(" + id0 + ") with PESSIMISTIC_WRITE lock");
Query q = em.createNamedQuery(namedQueryString);
if (extended) {
q = q.setHint("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED);
}
q = q.setParameter("firstName", "firstName%" + id0);
List<T> es = q.getResultList();
getLog().info(" *Found " + es.size() + " entity");
assertEquals(" *Found 1 entity", es.size(), 1);
verify.namedQueryPessimisticWriteDbSql(em);
e0 = es.get(0);
getLog().info(" *Found entity:" + e0);
assertNotNull(" *Found " + entityName + "(" + id0 + ")", e0);
assertEquals("Assert pessimistic write lock applied", LockModeType.PESSIMISTIC_WRITE, em.getLockMode(e0));
getLog().info(" *Ensure ReadLockLevel remains at level " + beforeReadMode);
assertEquals(" *Read lock should still be " + beforeReadMode + "after query set lock mode",
beforeReadLevel, getConfiguration(em).getReadLockLevelConstant());
getLog().info(
" *Find " + entityName + "(" + id1
+ ") with no lock to verify query lock set does not affect em lock mode.");
resetSQL();
e1 = em.find(type, id1);
getLog().info(" *" + (e1 != null ? "F" : "Can not f") + "ind an entity");
verify.findNoLockAfterNamedQueryPessimisticWriteDbSql(em);
getLog().info(" *Found entity:" + e1);
assertNotNull(" *Found " + entityName + "(" + id1 + ")", e1);
assertEquals(" *Assert default lock applied", LockModeType.NONE, em.getLockMode(e1));
getLog().info("Committing transaction.");
em.getTransaction().commit();
} finally {
em = null;
e0 = e1 = null;
if (em != null && em.isOpen()) {
em.close();
}
}
}
protected interface AssertCallback {
public void findNoLockDbSQL(EntityManager em);
public void findPessimisticForcIncDbSQL(EntityManager em);
public void queryPessimisticReadDbSQL(EntityManager em);
public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em);
public void namedQueryPessimisticWriteDbSql(EntityManager em);
public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em);
}
}

View File

@ -0,0 +1,937 @@
/*
* 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.lock.extended;
import javax.persistence.EntityManager;
/**
* LockScopeTestCase subclass to test entity with:
* - Uni-1x1 - eager fetch (default)
* - Uni-1x1 - lazy fetch
* - Uni-1x1 use join table - eager fetch (default)
* - Uni-1x1 use join table - lazy fetch
*/
public class Test1x1LockScope extends LockScopeTestCase {
public void setUp() {
setUp(LSE1x1Lf.class
, LSE1x1LfLzy.class
, LSE1x1LfJT.class
, LSE1x1LfJTLzy.class
, LSE1x1Rt.class
, "openjpa.LockManager", "mixed",
"openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)"
);
commonSetUp(LSE1x1Lf.class
, LSE1x1LfLzy.class
, LSE1x1LfJT.class
, LSE1x1LfJTLzy.class
, LSE1x1Rt.class
);
}
public void testNormalUni1x1Lock() {
common1x1Lock("testNormalUni1x1Lock", 1111201, false);
}
public void testExtendedUni1x1Lock() {
common1x1Lock("testExtendedUni1x1Lock", 1111211, true);
}
private void common1x1Lock(String testName, int idLf0, boolean extended) {
final String tableLfName = "LSE1x1Lf";
final String tableRtName = "LSE1x1Rt";
final String joinTables = tableLfName + ".*JOIN.*" + tableRtName;
getLog().info("** " + testName + "()");
String scope = extended ? "Extended" : "Normal";
int idRt0 = idLf0 + 10000; // right table
int idLf1 = idLf0 + 1;
int idRt1 = idRt0 + 1;
// create test entity.
LSE1x1Lf eLf0 = new LSE1x1Lf();
LSE1x1Rt eRt0 = new LSE1x1Rt();
eLf0.setId(idLf0);
eLf0.setFirstName("firstName " + idLf0);
eLf0.setUniRight(eRt0);
eRt0.setId(idRt0);
eRt0.setLastName("lastName " + idRt0);
LSE1x1Lf eLf1 = new LSE1x1Lf();
LSE1x1Rt eRt1 = new LSE1x1Rt();
eLf1.setId(idLf1);
eLf1.setFirstName("firstName " + idLf1);
eLf1.setUniRight(eRt1);
eRt1.setId(idRt1);
eRt1.setLastName("lastName " + idRt1);
EntityManager em = null;
try {
em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(eLf0);
em.persist(eRt0);
em.persist(eLf1);
em.persist(eRt1);
em.getTransaction().commit();
} finally {
em = null;
eLf0 = eLf1 = null;
eRt0 = eRt1 = null;
if (em != null && em.isOpen()) {
em.close();
}
}
commonLockTest(testName, LSE1x1Lf.class, idLf0, extended,
"SELECT c FROM LSE1x1Lf c WHERE c.firstName LIKE :firstName", "findLSE1x1Lf" + scope,
new AssertCallback() {
public void findNoLockDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// optimize for 1 row [params=(int) 1111201]
assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName
// FROM LSE1x1Lf t0, LSE1x1Rt t1 WHERE t0.id = ? AND t0.UNIRIGHT_ID = t1.id(+)
// [params=(int) 1111201]
assertLockTestSQLs(Select + tableLfName + ".*" + tableRtName + Where + "\\(\\+\\).*"
+ NoForUpdate);
break;
case derby:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// [params=(int) 1111201]
default:
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
}
}
public void findPessimisticForcIncDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1111202]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ?
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1121202]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ?
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1111202]
assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
break;
case oracle: // TODO: if jpa2, DO NOT lock LSE1x1RT using "FOR UPDATE OF col"
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName
// FROM LSE1x1Lf t0, LSE1x1Rt t1 WHERE t0.id = ? AND t0.UNIRIGHT_ID = t1.id(+)
// FOR UPDATE [params=(int) 1111202]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE [params=(int) 1121202]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? FOR UPDATE [params=(int) 1111202]
assertLockTestSQLs(Select + tableLfName + ".*" + tableRtName + Where + "\\(\\+\\).*"
+ ForUpdate);
break;
case derby: //TODO: **Non-atomic lock.
// The database is unable to lock this query. Each object matching the query will be
// locked individually after it is loaded; however, it is technically possible that
// another transaction could modify the data before the lock is obtained.
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// [params=(int) 1111202]
// SELECT t0.id FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1121202]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1121202]
// SELECT t0.id FROM LSE1x1Lf t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1111202]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1111202]
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
Select + tableLfName + ".*" + Where + ForUpdate,
Select + tableRtName + ".*" + Where + ForUpdate
);
break;
default:
assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
}
}
public void queryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.id, t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%1111201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1121201]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? [params=(int) 1111201]
assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
break;
case oracle: // TODO: if jpa2, DO NOT lock LSE1x1RT using "FOR UPDATE OF col"
// SELECT t0.id, t0.version, t0.firstName, t1.id, t1.version, t1.lastName
// FROM LSE1x1Lf t0, LSE1x1Rt t1
// WHERE (t0.firstName LIKE ?) AND t0.UNIRIGHT_ID = t1.id(+)
// FOR UPDATE [params=(String) firstName%1111201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1121201]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? [params=(int) 1111201]
assertLockTestSQLs(Select + tableLfName + ".*" + tableRtName + Where + "\\(\\+\\).*"
+ ForUpdate);
break;
case derby: //TODO: **Non-atomic lock.
// The database is unable to lock this query. Each object matching the query will be
// locked individually after it is loaded; however, it is technically possible that
// another transaction could modify the data before the lock is obtained.
//SELECT t0.id, t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id
// WHERE (t0.firstName LIKE ? ESCAPE '\') [params=(String) firstName%1111201]
// SELECT t0.id FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1121201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1121201]
// SELECT t0.id FROM LSE1x1Lf t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1111201]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? [params=(int) 1111201]
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
Select + tableLfName + ".*" + Where + ForUpdate,
Select + tableRtName + ".*" + Where + ForUpdate
);
break;
default:
assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
}
}
public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// optimize for 1 row [params=(int) 1111202]
assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName
// FROM LSE1x1Lf t0, LSE1x1Rt t1 WHERE t0.id = ? AND t0.UNIRIGHT_ID = t1.id(+)
// [params=(int) 1111202]
assertLockTestSQLs(Select + tableLfName + ".*" + tableRtName + Where + "\\(\\+\\).*"
+ NoForUpdate);
break;
case derby:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// [params=(int) 1111202]
default:
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
}
}
public void namedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.id, t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%1111201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1121201]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? [params=(int) 1111201]
assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
break;
case oracle: // TODO: if jpa2, DO NOT lock LSE1x1RT using "FOR UPDATE OF col"
// SELECT t0.id, t0.version, t0.firstName, t1.id, t1.version, t1.lastName
// FROM LSE1x1Lf t0, LSE1x1Rt t1
// WHERE (t0.firstName LIKE ?) AND t0.UNIRIGHT_ID = t1.id(+)
// FOR UPDATE [params=(String) firstName%1111201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1121201]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? [params=(int) 1111201]
assertLockTestSQLs(Select + tableLfName + ".*" + tableRtName + Where + "\\(\\+\\).*"
+ ForUpdate);
break;
case derby: //TODO: **Non-atomic lock.
// The database is unable to lock this query. Each object matching the query will be
// locked individually after it is loaded; however, it is technically possible that
// another transaction could modify the data before the lock is obtained.
// SELECT t0.id, t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id
// WHERE (t0.firstName LIKE ? ESCAPE '\') [params=(String) firstName%1111201]
// SELECT t0.id FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1121201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1121201]
// SELECT t0.id FROM LSE1x1Lf t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1111201]
// SELECT t0.version FROM LSE1x1Lf t0 WHERE t0.id = ? [params=(int) 1111201]
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
Select + tableLfName + ".*" + Where + ForUpdate,
Select + tableRtName + ".*" + Where + ForUpdate
);
break;
default:
assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
}
}
public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// optimize for 1 row [params=(int) 1111202]
assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName
// FROM LSE1x1Lf t0, LSE1x1Rt t1 WHERE t0.id = ? AND t0.UNIRIGHT_ID = t1.id(+)
// [params=(int) 1111202]
assertLockTestSQLs(Select + tableLfName + ".*" + tableRtName + Where + "\\(\\+\\).*"
+ NoForUpdate);
break;
case derby:
// SELECT t0.version, t0.firstName, t1.id, t1.version, t1.lastName FROM LSE1x1Lf t0
// LEFT OUTER JOIN LSE1x1Rt t1 ON t0.UNIRIGHT_ID = t1.id WHERE t0.id = ?
// [params=(int) 1111202]
default:
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
}
}
});
}
public void testNormalUni1x1LazyLock() {
common1x1LazyLock("testNormalUni1x1LazyLock", 1111101, false);
}
public void testExtendedUni1x1LazyLock() {
common1x1LazyLock("testExtendedUni1x1LazyLock", 1111111, true);
}
private void common1x1LazyLock(String testName, int idLf0, boolean extended) {
final String tableLfName = "LSE1x1LfLzy";
// final String tableRtName = "LockSEUni1x1RT";
getLog().info("** " + testName + "()");
String scope = extended ? "Extended" : "Normal";
int idRt0 = idLf0 + 10000; // right table
int idLf1 = idLf0 + 1;
int idRt1 = idRt0 + 1;
// create test entity.
LSE1x1LfLzy eLf0 = new LSE1x1LfLzy();
LSE1x1Rt eRt0 = new LSE1x1Rt();
eLf0.setId(idLf0);
eLf0.setFirstName("firstName " + idLf0);
eLf0.setUniRight(eRt0);
eRt0.setId(idRt0);
eRt0.setLastName("lastName " + idRt0);
LSE1x1LfLzy eLf1 = new LSE1x1LfLzy();
LSE1x1Rt eRt1 = new LSE1x1Rt();
eLf1.setId(idLf1);
eLf1.setFirstName("firstName " + idLf1);
eLf1.setUniRight(eRt1);
eRt1.setId(idRt1);
eRt1.setLastName("lastName " + idRt1);
EntityManager em = null;
try {
em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(eLf0);
em.persist(eRt0);
em.persist(eLf1);
em.persist(eRt1);
em.getTransaction().commit();
} finally {
em = null;
eLf0 = eLf1 = null;
eRt0 = eRt1 = null;
if (em != null && em.isOpen()) {
em.close();
}
}
commonLockTest(testName, LSE1x1LfLzy.class, idLf0, extended,
"SELECT c FROM LSE1x1LfLzy c WHERE c.firstName LIKE :firstName", "findLSE1x1LfLzy" + scope,
new AssertCallback() {
public void findNoLockDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// optimize for 1 row [params=(int) 1111101]
assertLockTestSQLs(Select + tableLfName + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// [params=(int) 1111101]
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// [params=(int) 1111101]
default:
assertLockTestSQLs(Select + tableLfName + Where + NoForUpdate);
}
}
public void findPessimisticForcIncDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS
// [params=(int) 1111102]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1111102]
assertLockTestSQLs(Select + tableLfName + Where + DB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// FOR UPDATE [params=(int) 1111102]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? FOR UPDATE [params=(int) 1111102]
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ? FOR UPDATE WITH RR
// [params=(int) 1111102]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? FOR UPDATE WITH RR
// [params=(int) 1111102]
default:
assertLockTestSQLs(Select + tableLfName + Where + ForUpdate);
}
}
public void queryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%1111101]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? [params=(int) 1111101]
assertLockTestSQLs(Select + tableLfName + Where + DB2Lock);
break;
case oracle:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE (t0.firstName LIKE ?)
// FOR UPDATE [params=(String) firstName%1111101]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? [params=(int) 1111101]
case derby:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR
// [params=(String) firstName%1111101]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? [params=(int) 1111101]
default:
assertLockTestSQLs(Select + tableLfName + Where + ForUpdate);
}
}
public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// optimize for 1 row [params=(int) 1111102]
assertLockTestSQLs(Select + tableLfName + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// [params=(int) 1111102]
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// [params=(int) 1111102]
default:
assertLockTestSQLs(Select + tableLfName + Where + NoForUpdate);
}
}
public void namedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%1111101]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? [params=(int) 1111101]
assertLockTestSQLs(Select + tableLfName + Where + DB2Lock);
break;
case oracle:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE (t0.firstName LIKE ?)
// FOR UPDATE [params=(String) firstName%1111101]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? [params=(int) 1111101]
case derby:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR
// [params=(String) firstName%1111101]
// SELECT t0.version FROM LSE1x1LfLzy t0 WHERE t0.id = ? [params=(int) 1111101]
default:
assertLockTestSQLs(Select + tableLfName + Where + ForUpdate);
}
}
public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// optimize for 1 row [params=(int) 1111102]
assertLockTestSQLs(Select + tableLfName + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// [params=(int) 1111102]
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfLzy t0 WHERE t0.id = ?
// [params=(int) 1111102]
default:
assertLockTestSQLs(Select + tableLfName + Where + NoForUpdate);
}
}
});
}
public void testNormalUni1x1JTLock() {
common1x1JTLock("testNormalUni1x1JTLock", 1112201, false);
}
public void testExtendedUni1x1JTLock() {
common1x1JTLock("testExtendedUni1x1JTLock", 1112211, true);
}
private void common1x1JTLock(String testName, int idLf0, boolean extended) {
final String tableLfName = "LSE1x1LfJT";
final String tableJTName = "Uni1x1LfJT_Uni1x1RT";
final String tableRtName = "LSE1x1Rt";
final String joinTables = tableLfName + ".*JOIN.*" + tableJTName + ".*JOIN.*" + tableRtName;
getLog().info("** " + testName + "()");
String scope = extended ? "Extended" : "Normal";
int idRt0 = idLf0 + 10000; // right table
int idLf1 = idLf0 + 1;
int idRt1 = idRt0 + 1;
// create test entity.
LSE1x1LfJT eLf0 = new LSE1x1LfJT();
LSE1x1Rt eRt0 = new LSE1x1Rt();
eLf0.setId(idLf0);
eLf0.setFirstName("firstName " + idLf0);
eLf0.setUniRightJT(eRt0);
eRt0.setId(idRt0);
eRt0.setLastName("lastName " + idRt0);
LSE1x1LfJT eLf1 = new LSE1x1LfJT();
LSE1x1Rt eRt1 = new LSE1x1Rt();
eLf1.setId(idLf1);
eLf1.setFirstName("firstName " + idLf1);
eLf1.setUniRightJT(eRt1);
eRt1.setId(idRt1);
eRt1.setLastName("lastName " + idRt1);
EntityManager em = null;
try {
em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(eLf0);
em.persist(eRt0);
em.persist(eLf1);
em.persist(eRt1);
em.getTransaction().commit();
} finally {
em = null;
eLf0 = eLf1 = null;
eRt0 = eRt1 = null;
if (em != null && em.isOpen()) {
em.close();
}
}
commonLockTest(testName, LSE1x1LfJT.class, idLf0, extended,
"SELECT c FROM LSE1x1LfJT c WHERE c.firstName LIKE :firstName", "findLSE1x1LfJT" + scope,
new AssertCallback() {
public void findNoLockDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id WHERE t0.id = ?
// optimize for 1 row [params=(int) 1112201]
assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName
// FROM LSE1x1LfJT t0, Uni1x1LfJT_Uni1x1RT t1, LSE1x1Rt t2
// WHERE t0.id = ? AND t0.id = t1.LSE1X1LFJT_ID AND t1.UNIRIGHTJT_ID = t2.id(+)
// [params=(int) 1112201]
assertLockTestSQLs(Select + tableLfName + ".*" + tableJTName + ".*" + tableRtName + Where
+ "\\(\\+\\).*" + NoForUpdate);
break;
case derby:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id WHERE t0.id = ?
// [params=(int) 1112201]
default:
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
}
}
public void findPessimisticForcIncDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id WHERE t0.id = ?
// optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1112202]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1122202]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1112202]
assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
break;
case oracle: // TODO: If jpa2, DO NOT lock LSE1x1RT using "FOR UDPATE OF col"
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName
// FROM LSE1x1LfJT t0, Uni1x1LfJT_Uni1x1RT t1, LSE1x1Rt t2
// WHERE t0.id = ? AND t0.id = t1.LSE1X1LFJT_ID AND t1.UNIRIGHTJT_ID = t2.id(+)
// FOR UPDATE [params=(int) 1112202]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE [params=(int) 1122202]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? FOR UPDATE [params=(int) 1112202]
assertLockTestSQLs(Select + tableLfName + ".*" + tableJTName + ".*" + tableRtName + Where
+ "\\(\\+\\).*" + ForUpdate);
break;
case derby: //TODO: **Non-atomic lock, if jpa2/extended scope, LOCK Uni1x1LfJT_Uni1x1RT
// DO NOT lock LSE1x1Rt
// The database is unable to lock this query. Each object matching the query will be
// locked individually after it is loaded; however, it is technically possible that
// another transaction could modify the data before the lock is obtained.
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id WHERE t0.id = ?
// [params=(int) 1112202]
// SELECT t0.id FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1122202]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1122202]
// SELECT t0.id FROM LSE1x1LfJT t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1112202]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1112202]
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
Select + tableLfName + ".*" + Where + ForUpdate,
Select + tableRtName + ".*" + Where + ForUpdate
);
break;
default:
assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
}
}
public void queryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.id, t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%1112201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1122201]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? [params=(int) 1112201]
assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
break;
case oracle: // TODO: If jpa2, DO NOT lock LSE1x1RT using "FOR UDPATE OF col"
// SELECT t0.id, t0.version, t0.firstName, t2.id, t2.version, t2.lastName
// FROM LSE1x1LfJT t0, Uni1x1LfJT_Uni1x1RT t1, LSE1x1Rt t2
// WHERE (t0.firstName LIKE ?) AND t0.id = t1.LSE1X1LFJT_ID
// AND t1.UNIRIGHTJT_ID = t2.id(+) FOR UPDATE [params=(String) firstName%1112201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1122201]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? [params=(int) 1112201]
assertLockTestSQLs(Select + tableLfName + ".*" + tableJTName + ".*" + tableRtName + Where
+ "\\(\\+\\).*" + ForUpdate);
break;
case derby: //TODO: **Non-atomic lock, if jpa2/extended scope, LOCK Uni1x1LfJT_Uni1x1RT
// DO NOT lock LSE1x1Rt
// The database is unable to lock this query. Each object matching the query will be
// locked individually after it is loaded; however, it is technically possible that
// another transaction could modify the data before the lock is obtained.
// SELECT t0.id, t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id
// WHERE (t0.firstName LIKE ? ESCAPE '\') [params=(String) firstName%1112201]
// SELECT t0.id FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1122201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1122201]
// SELECT t0.id FROM LSE1x1LfJT t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1112201]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? [params=(int) 1112201]
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
Select + tableLfName + ".*" + Where + ForUpdate,
Select + tableRtName + ".*" + Where + ForUpdate
);
break;
default:
assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
}
}
public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id WHERE t0.id = ?
// optimize for 1 row [params=(int) 1112202]
assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName
// FROM LSE1x1LfJT t0, Uni1x1LfJT_Uni1x1RT t1, LSE1x1Rt t2
// WHERE t0.id = ? AND t0.id = t1.LSE1X1LFJT_ID AND t1.UNIRIGHTJT_ID = t2.id(+)
// [params=(int) 1112202]
assertLockTestSQLs(Select + tableLfName + ".*" + tableJTName + ".*" + tableRtName + Where
+ "\\(\\+\\).*" + NoForUpdate);
break;
case derby:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id WHERE t0.id = ?
// [params=(int) 1112202]
default:
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
}
}
public void namedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) {
case db2:
//SELECT t0.id, t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%1112201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1122201]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? [params=(int) 1112201]
assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
break;
case oracle: // TODO: If jpa2, DO NOT lock LSE1x1RT using "FOR UDPATE OF col"
// SELECT t0.id, t0.version, t0.firstName, t2.id, t2.version, t2.lastName
// FROM LSE1x1LfJT t0, Uni1x1LfJT_Uni1x1RT t1, LSE1x1Rt t2
// WHERE (t0.firstName LIKE ?) AND t0.id = t1.LSE1X1LFJT_ID
// AND t1.UNIRIGHTJT_ID = t2.id(+) FOR UPDATE [params=(String) firstName%1112201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1122201]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? [params=(int) 1112201]
assertLockTestSQLs(Select + tableLfName + ".*" + tableJTName + ".*" + tableRtName + Where
+ "\\(\\+\\).*" + ForUpdate);
break;
case derby: //TODO: **Non-atomic lock, if jpa2/extended scope, LOCK Uni1x1LfJT_Uni1x1RT
// DO NOT lock LSE1x1Rt
// The database is unable to lock this query. Each object matching the query will be
// locked individually after it is loaded; however, it is technically possible that
// another transaction could modify the data before the lock is obtained.
// SELECT t0.id, t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id
// WHERE (t0.firstName LIKE ? ESCAPE '\') [params=(String) firstName%1112201]
// SELECT t0.id FROM LSE1x1Rt t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1122201]
// SELECT t0.version FROM LSE1x1Rt t0 WHERE t0.id = ? [params=(int) 1122201]
// SELECT t0.id FROM LSE1x1LfJT t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1112201]
// SELECT t0.version FROM LSE1x1LfJT t0 WHERE t0.id = ? [params=(int) 1112201]
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
Select + tableLfName + ".*" + Where + ForUpdate,
Select + tableRtName + ".*" + Where + ForUpdate
);
break;
default:
assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
}
}
public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id WHERE t0.id = ?
// optimize for 1 row [params=(int) 1112202]
assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName
// FROM LSE1x1LfJT t0, Uni1x1LfJT_Uni1x1RT t1, LSE1x1Rt t2
// WHERE t0.id = ? AND t0.id = t1.LSE1X1LFJT_ID AND t1.UNIRIGHTJT_ID = t2.id(+)
// [params=(int) 1112202]
assertLockTestSQLs(Select + tableLfName + ".*" + tableJTName + ".*" + tableRtName + Where
+ "\\(\\+\\).*" + NoForUpdate);
break;
case derby:
// SELECT t0.version, t0.firstName, t2.id, t2.version, t2.lastName FROM LSE1x1LfJT t0
// INNER JOIN Uni1x1LfJT_Uni1x1RT t1 ON t0.id = t1.LSE1X1LFJT_ID
// LEFT OUTER JOIN LSE1x1Rt t2 ON t1.UNIRIGHTJT_ID = t2.id
// WHERE t0.id = ? [params=(int) 1112202]
default:
assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
}
}
});
}
public void testNormalUni1x1JTLazyLock() {
common1x1JTLazyLock("testNormalUni1x1JTLazyLock", 1112101, false);
}
public void testExtendedUni1x1JTLazyLock() {
common1x1JTLazyLock("testExtendedUni1x1JTLazyLock", 1112111, true);
}
private void common1x1JTLazyLock(String testName, int idLf0, boolean extended) {
final String tableLfName = "LSE1x1LfJTLzy";
// final String tableRtName = "LockSEUni1x1RT";
getLog().info("** " + testName + "()");
String scope = extended ? "Extended" : "Normal";
int idRt0 = idLf0 + 10000; // right table
int idLf1 = idLf0 + 1;
int idRt1 = idRt0 + 1;
// create test entity.
LSE1x1LfJTLzy eLf0 = new LSE1x1LfJTLzy();
LSE1x1Rt eRt0 = new LSE1x1Rt();
eLf0.setId(idLf0);
eLf0.setFirstName("firstName " + idLf0);
eLf0.setUniRightJT(eRt0);
eRt0.setId(idRt0);
eRt0.setLastName("lastName " + idRt0);
LSE1x1LfJTLzy eLf1 = new LSE1x1LfJTLzy();
LSE1x1Rt eRt1 = new LSE1x1Rt();
eLf1.setId(idLf1);
eLf1.setFirstName("firstName " + idLf1);
eLf1.setUniRightJT(eRt1);
eRt1.setId(idRt1);
eRt1.setLastName("lasttName " + idRt1);
EntityManager em = null;
try {
em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(eLf0);
em.persist(eRt0);
em.persist(eLf1);
em.persist(eRt1);
em.getTransaction().commit();
} finally {
em = null;
eLf0 = eLf1 = null;
eRt0 = eRt1 = null;
if (em != null && em.isOpen()) {
em.close();
}
}
commonLockTest(testName, LSE1x1LfJTLzy.class, idLf0, extended,
"SELECT c FROM LSE1x1LfJTLzy c WHERE c.firstName LIKE :firstName", "findLSE1x1LfJTLzy" + scope,
new AssertCallback() {
public void findNoLockDbSQL(EntityManager em) {
switch (getDBType(em)) {
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// optimize for 1 row [params=(int) 1112101]
assertLockTestSQLs(Select + tableLfName + Where + NoDB2Lock);
break;
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// [params=(int) 1112101]
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// [params=(int) 1112101]
default:
assertLockTestSQLs(Select + tableLfName + Where + NoForUpdate);
}
}
public void findPessimisticForcIncDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS
// [params=(int) 1112102]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1112102]
assertLockTestSQLs(Select + tableLfName + Where + DB2Lock);
break;
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? FOR UPDATE WITH RR
// [params=(int) 1112102]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? FOR UPDATE WITH RR
// [params=(int) 1112102]
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? FOR UPDATE
// [params=(int) 1112102]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? FOR UPDATE [params=(int) 1112102]
default:
assertLockTestSQLs(Select + tableLfName + Where + ForUpdate);
}
}
public void queryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfJTLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%1112101]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? [params=(int) 1112101]
assertLockTestSQLs(Select + tableLfName + Where + DB2Lock);
break;
case derby:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfJTLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR
// [params=(String) firstName%1112101]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? [params=(int) 1112101]
case oracle:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfJTLzy t0
// WHERE (t0.firstName LIKE ?) FOR UPDATE [params=(String) firstName%1112101]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? [params=(int) 1112101]
default:
assertLockTestSQLs(Select + tableLfName + Where + ForUpdate);
}
}
public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// optimize for 1 row [params=(int) 1112102]
assertLockTestSQLs(Select + tableLfName + Where + NoDB2Lock);
break;
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// [params=(int) 1112102]
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// [params=(int) 1112102]
default:
assertLockTestSQLs(Select + tableLfName + Where + NoForUpdate);
}
}
public void namedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfJTLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\')
// FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%1112101]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? [params=(int) 1112101]
assertLockTestSQLs(Select + tableLfName + Where + DB2Lock);
break;
case derby:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfJTLzy t0
// WHERE (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR
// [params=(String) firstName%1112101]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? [params=(int) 1112101]
case oracle:
// SELECT t0.id, t0.version, t0.firstName FROM LSE1x1LfJTLzy t0
// WHERE (t0.firstName LIKE ?) FOR UPDATE [params=(String) firstName%1112101]
// SELECT t0.version FROM LSE1x1LfJTLzy t0 WHERE t0.id = ? [params=(int) 1112101]
default:
assertLockTestSQLs(Select + tableLfName + Where + ForUpdate);
}
}
public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
switch (getDBType(em)) { // **Check
case db2:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// optimize for 1 row [params=(int) 1112102]
assertLockTestSQLs(Select + tableLfName + Where + NoDB2Lock);
break;
case derby:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// [params=(int) 1112102]
case oracle:
// SELECT t0.version, t0.firstName FROM LSE1x1LfJTLzy t0 WHERE t0.id = ?
// [params=(int) 1112102]
default:
assertLockTestSQLs(Select + tableLfName + Where + NoForUpdate);
}
}
});
}
}

View File

@ -61,8 +61,6 @@ import javax.persistence.FlushModeType;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.IdClass; import javax.persistence.IdClass;
import javax.persistence.Lob; import javax.persistence.Lob;
@ -1772,7 +1770,9 @@ public class AnnotationPersistenceMetaDataParser
meta.setLanguage(JPQLParser.LANG_JPQL); meta.setLanguage(JPQLParser.LANG_JPQL);
for (QueryHint hint : query.hints()) for (QueryHint hint : query.hints())
meta.addHint(hint.name(), hint.value()); meta.addHint(hint.name(), hint.value());
if (query.lockMode() != null) {
meta.addHint("openjpa.FetchPlan.ReadLockMode", query.lockMode());
}
meta.setSource(getSourceFile(), (el instanceof Class) ? el : null, meta.setSource(getSourceFile(), (el instanceof Class) ? el : null,
SourceTracker.SRC_ANNOTATIONS); SourceTracker.SRC_ANNOTATIONS);
if (isMetaDataMode()) if (isMetaDataMode())

View File

@ -20,9 +20,9 @@ package org.apache.openjpa.persistence;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.persistence.LockModeType; import javax.persistence.LockModeType;
import javax.persistence.PessimisticLockScope;
import org.apache.openjpa.kernel.DataCacheRetrieveMode; import org.apache.openjpa.kernel.DataCacheRetrieveMode;
import org.apache.openjpa.kernel.DataCacheStoreMode; import org.apache.openjpa.kernel.DataCacheStoreMode;
@ -321,6 +321,16 @@ public interface FetchPlan {
*/ */
public FetchPlan setLockTimeout(int timeout); public FetchPlan setLockTimeout(int timeout);
/**
* The lock scope to use for locking loaded objects.
*/
public PessimisticLockScope getLockScope();
/**
* The lock scope to use for locking loaded objects.
*/
public FetchPlan setLockScope(PessimisticLockScope scope);
/** /**
* The number of milliseconds to wait for a query, or -1 for no * The number of milliseconds to wait for a query, or -1 for no
* limit. * limit.

View File

@ -59,6 +59,7 @@ public class FetchPlanHintHandler extends AbstractHintHandler {
} }
// Initialize javax.persistence to openjpa.FetchPlan hint mapping. // Initialize javax.persistence to openjpa.FetchPlan hint mapping.
javaxHintsMap.put(JPAProperties.LOCK_TIMEOUT, PREFIX_FETCHPLAN + "LockTimeout"); javaxHintsMap.put(JPAProperties.LOCK_TIMEOUT, PREFIX_FETCHPLAN + "LockTimeout");
javaxHintsMap.put(JPAProperties.LOCK_SCOPE, PREFIX_FETCHPLAN + "LockScope");
javaxHintsMap.put(JPAProperties.QUERY_TIMEOUT, PREFIX_FETCHPLAN + "QueryTimeout"); javaxHintsMap.put(JPAProperties.QUERY_TIMEOUT, PREFIX_FETCHPLAN + "QueryTimeout");
// Initialize hint precedence order mapping from list. // Initialize hint precedence order mapping from list.
String[][] precedenceMapList = { String[][] precedenceMapList = {
@ -66,6 +67,10 @@ public class FetchPlanHintHandler extends AbstractHintHandler {
PREFIX_FETCHPLAN + "LockTimeout", PREFIX_FETCHPLAN + "LockTimeout",
PREFIX_OPENJPA + "LockTimeout" }, PREFIX_OPENJPA + "LockTimeout" },
{ JPAProperties.LOCK_SCOPE,
PREFIX_FETCHPLAN + "LockScope",
PREFIX_OPENJPA + "LockScope" },
{ JPAProperties.QUERY_TIMEOUT, { JPAProperties.QUERY_TIMEOUT,
PREFIX_FETCHPLAN + "QueryTimeout", PREFIX_FETCHPLAN + "QueryTimeout",
PREFIX_OPENJPA + "QueryTimeout" }, PREFIX_OPENJPA + "QueryTimeout" },

View File

@ -25,6 +25,7 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import javax.persistence.LockModeType; import javax.persistence.LockModeType;
import javax.persistence.PessimisticLockScope;
import org.apache.openjpa.kernel.DataCacheRetrieveMode; import org.apache.openjpa.kernel.DataCacheRetrieveMode;
import org.apache.openjpa.kernel.DataCacheStoreMode; import org.apache.openjpa.kernel.DataCacheStoreMode;
@ -237,6 +238,15 @@ public class FetchPlanImpl
return this; return this;
} }
public PessimisticLockScope getLockScope() {
return LockScopesHelper.fromLockScope(_fetch.getLockScope());
}
public FetchPlan setLockScope(PessimisticLockScope scope) {
_fetch.setLockScope(LockScopesHelper.toLockScope(scope));
return this;
}
public int getQueryTimeout() { public int getQueryTimeout() {
return _fetch.getQueryTimeout(); return _fetch.getQueryTimeout();
} }

View File

@ -0,0 +1,49 @@
/*
* 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;
import javax.persistence.PessimisticLockScope;
import org.apache.openjpa.kernel.LockScopes;
/**
* Helper methods translate between JPA-defined pessimistic lock scope and
* OpenJPA internal lock scope levels.
*
* @since 2.0.0
*/
public class LockScopesHelper {
/**
* Translates javax.persistence LockModeType to internal lock level.
*/
public static int toLockScope(PessimisticLockScope scope) {
if (scope == null || scope == PessimisticLockScope.NORMAL)
return LockScopes.LOCKSCOPE_NORMAL;
return LockScopes.LOCKSCOPE_EXTENDED;
}
/**
* Translates internal lock level to javax.persistence LockModeType.
*/
public static PessimisticLockScope fromLockScope(int level) {
if (level < LockScopes.LOCKSCOPE_EXTENDED)
return PessimisticLockScope.NORMAL;
return PessimisticLockScope.EXTENDED;
}
}

View File

@ -31,15 +31,14 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Stack; import java.util.Stack;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.LockModeType;
import static javax.persistence.CascadeType.*; import static javax.persistence.CascadeType.*;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.apache.openjpa.conf.OpenJPAConfiguration; import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PersistenceCapable; import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.event.BeanLifecycleCallbacks; import org.apache.openjpa.event.BeanLifecycleCallbacks;
@ -61,7 +60,6 @@ import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.LifecycleMetaData; import org.apache.openjpa.meta.LifecycleMetaData;
import org.apache.openjpa.meta.MetaDataContext; import org.apache.openjpa.meta.MetaDataContext;
import org.apache.openjpa.meta.MetaDataDefaults;
import org.apache.openjpa.meta.MetaDataFactory; import org.apache.openjpa.meta.MetaDataFactory;
import static org.apache.openjpa.meta.MetaDataModes.*; import static org.apache.openjpa.meta.MetaDataModes.*;
import org.apache.openjpa.meta.MetaDataRepository; import org.apache.openjpa.meta.MetaDataRepository;
@ -73,6 +71,9 @@ import static org.apache.openjpa.persistence.MetaDataTag.*;
import static org.apache.openjpa.persistence.PersistenceStrategy.*; import static org.apache.openjpa.persistence.PersistenceStrategy.*;
import org.apache.openjpa.util.ImplHelper; import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.MetaDataException; import org.apache.openjpa.util.MetaDataException;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import serp.util.Numbers; import serp.util.Numbers;
@ -1106,7 +1107,7 @@ public class XMLPersistenceMetaDataParser
throws SAXException { throws SAXException {
FieldMetaData fmd = (FieldMetaData) currentElement(); FieldMetaData fmd = (FieldMetaData) currentElement();
int typeCode = fmd.isElementCollection() ? fmd.getElement().getDeclaredTypeCode() : fmd.getDeclaredTypeCode(); int typeCode = fmd.isElementCollection() ? fmd.getElement().getDeclaredTypeCode() : fmd.getDeclaredTypeCode();
Class type = fmd.isElementCollection() ? fmd.getElement().getDeclaredType() : fmd.getDeclaredType(); Class<?> type = fmd.isElementCollection() ? fmd.getElement().getDeclaredType() : fmd.getDeclaredType();
if (typeCode != JavaTypes.STRING if (typeCode != JavaTypes.STRING
&& type != char[].class && type != char[].class
&& type != Character[].class && type != Character[].class
@ -1651,12 +1652,10 @@ public class XMLPersistenceMetaDataParser
meta.setDefiningType(_cls); meta.setDefiningType(_cls);
meta.setQueryString(attrs.getValue("query")); meta.setQueryString(attrs.getValue("query"));
meta.setLanguage(JPQLParser.LANG_JPQL); meta.setLanguage(JPQLParser.LANG_JPQL);
/** TODO: Uncomment when orm.xsd defines lockmode String lockModeStr = attrs.getValue("lock-mode");
LockModeType lockMode = if (lockModeStr != null) {
LockModeType.valueOf(attrs.getValue("lockMode")); meta.addHint("openjpa.FetchPlan.ReadLockMode", LockModeType.valueOf(lockModeStr));
meta.addHint("openjpa.FetchPlan.ReadLockMode", }
JPA2LockLevels.toLockLevel(lockMode));
**/
Locator locator = getLocation().getLocator(); Locator locator = getLocation().getLocator();
if (locator != null) { if (locator != null) {
meta.setLineNumber(Numbers.valueOf(locator.getLineNumber())); meta.setLineNumber(Numbers.valueOf(locator.getLineNumber()));