[New] implemented a test to allow multiple operations
This test makes sure that updating after adding, or any other operation in the same TX works properly. Found a problem where the PersistenceContext didn't implement hashCode() and equals() which lead to each operation being added even though a previous operation was already registered
This commit is contained in:
parent
3c623bd20c
commit
3c006b541a
|
@ -52,4 +52,43 @@ public class PersistenceContext<T> {
|
|||
public void setParserFactory(ParserFactory<T> parserFactory) {
|
||||
this.parserFactory = parserFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.objectRef == null) ? 0 : this.objectRef.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PersistenceContext<?> other = (PersistenceContext<?>) obj;
|
||||
if (this.objectRef == null) {
|
||||
if (other.objectRef != null)
|
||||
return false;
|
||||
} else if (!this.objectRef.equals(other.objectRef))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("PersistenceContext [objectRef=");
|
||||
builder.append(this.objectRef);
|
||||
builder.append(", object=");
|
||||
builder.append(this.object);
|
||||
builder.append(", parserFactory=");
|
||||
builder.append(this.parserFactory);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -73,8 +73,50 @@ public class IdOfSubTypeRef extends ObjectRef {
|
|||
@Override
|
||||
public <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx) {
|
||||
PersistenceContextFactoryDelegator ctxFactoryDelegator = tx.getRealm().getCtxFactoryDelegator();
|
||||
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator
|
||||
.<T> getCtxFactory(this.type);
|
||||
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator.<T> getCtxFactory(this.type);
|
||||
return persistenceContextFactory.createCtx(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
|
||||
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
|
||||
result = prime * result + ((this.subType == null) ? 0 : this.subType.hashCode());
|
||||
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
IdOfSubTypeRef other = (IdOfSubTypeRef) obj;
|
||||
if (this.realmName == null) {
|
||||
if (other.realmName != null)
|
||||
return false;
|
||||
} else if (!this.realmName.equals(other.realmName))
|
||||
return false;
|
||||
if (this.id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!this.id.equals(other.id))
|
||||
return false;
|
||||
if (this.subType == null) {
|
||||
if (other.subType != null)
|
||||
return false;
|
||||
} else if (!this.subType.equals(other.subType))
|
||||
return false;
|
||||
if (this.type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!this.type.equals(other.type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,8 +67,44 @@ public class IdOfTypeRef extends ObjectRef {
|
|||
@Override
|
||||
public <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx) {
|
||||
PersistenceContextFactoryDelegator ctxFactoryDelegator = tx.getRealm().getCtxFactoryDelegator();
|
||||
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator
|
||||
.<T> getCtxFactory(this.type);
|
||||
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator.<T> getCtxFactory(this.type);
|
||||
return persistenceContextFactory.createCtx(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
|
||||
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
|
||||
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
IdOfTypeRef other = (IdOfTypeRef) obj;
|
||||
if (this.realmName == null) {
|
||||
if (other.realmName != null)
|
||||
return false;
|
||||
} else if (!this.realmName.equals(other.realmName))
|
||||
return false;
|
||||
if (this.id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!this.id.equals(other.id))
|
||||
return false;
|
||||
if (this.type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!this.type.equals(other.type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import ch.eitchnet.xmlpers.impl.PathBuilder;
|
|||
|
||||
public abstract class ObjectRef extends LockableObject {
|
||||
|
||||
private String realmName;
|
||||
private String name;
|
||||
protected final String realmName;
|
||||
protected final String name;
|
||||
|
||||
protected ObjectRef(String realmName, String name) {
|
||||
this.realmName = realmName;
|
||||
|
@ -44,4 +44,10 @@ public abstract class ObjectRef extends LockableObject {
|
|||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract boolean equals(Object obj);
|
||||
|
||||
@Override
|
||||
public abstract int hashCode();
|
||||
}
|
||||
|
|
|
@ -56,4 +56,29 @@ public class RootRef extends ObjectRef {
|
|||
String msg = MessageFormat.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
|
||||
throw new UnsupportedOperationException(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RootRef other = (RootRef) obj;
|
||||
if (this.realmName == null) {
|
||||
if (other.realmName != null)
|
||||
return false;
|
||||
} else if (!this.realmName.equals(other.realmName))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,41 @@ public class SubTypeRef extends ObjectRef {
|
|||
String msg = MessageFormat.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
|
||||
throw new UnsupportedOperationException(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
|
||||
result = prime * result + ((this.subType == null) ? 0 : this.subType.hashCode());
|
||||
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SubTypeRef other = (SubTypeRef) obj;
|
||||
if (this.realmName == null) {
|
||||
if (other.realmName != null)
|
||||
return false;
|
||||
} else if (!this.realmName.equals(other.realmName))
|
||||
return false;
|
||||
if (this.subType == null) {
|
||||
if (other.subType != null)
|
||||
return false;
|
||||
} else if (!this.subType.equals(other.subType))
|
||||
return false;
|
||||
if (this.type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!this.type.equals(other.type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,4 +56,35 @@ public class TypeRef extends ObjectRef {
|
|||
String msg = MessageFormat.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
|
||||
throw new UnsupportedOperationException(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
|
||||
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TypeRef other = (TypeRef) obj;
|
||||
if (this.realmName == null) {
|
||||
if (other.realmName != null)
|
||||
return false;
|
||||
} else if (!this.realmName.equals(other.realmName))
|
||||
return false;
|
||||
if (this.type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!this.type.equals(other.type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ package javanet.staxutils;
|
|||
* Characters that represent line breaks and indentation. These are represented
|
||||
* as String-valued JavaBean properties.
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
public interface Indentation {
|
||||
|
||||
/** Two spaces; the default indentation. */
|
||||
public static final String DEFAULT_INDENT = " ";
|
||||
public static final String DEFAULT_INDENT = " ";
|
||||
|
||||
/**
|
||||
* Set the characters used for one level of indentation. The default is
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
package javanet.staxutils;
|
||||
|
||||
import javanet.staxutils.helpers.StreamWriterDelegate;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
|
||||
|
@ -68,6 +69,7 @@ import javax.xml.stream.XMLStreamWriter;
|
|||
*
|
||||
* @author <a href="mailto:jk2006@engineer.com">John Kristian</a>
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
public class IndentingXMLStreamWriter extends StreamWriterDelegate implements Indentation {
|
||||
|
||||
public IndentingXMLStreamWriter(XMLStreamWriter out) {
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
*/
|
||||
package ch.eitchnet.xmlpers.test;
|
||||
|
||||
import static ch.eitchnet.xmlpers.test.impl.TestConstants.TYPE_RES;
|
||||
import static ch.eitchnet.xmlpers.test.model.ModelBuilder.RES_ID;
|
||||
import static ch.eitchnet.xmlpers.test.model.ModelBuilder.RES_TYPE;
|
||||
import static ch.eitchnet.xmlpers.test.model.ModelBuilder.assertResource;
|
||||
import static ch.eitchnet.xmlpers.test.model.ModelBuilder.assertResourceUpdated;
|
||||
import static ch.eitchnet.xmlpers.test.model.ModelBuilder.createResource;
|
||||
import static ch.eitchnet.xmlpers.test.model.ModelBuilder.updateResource;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
@ -36,12 +38,15 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import ch.eitchnet.xmlpers.api.IoMode;
|
||||
import ch.eitchnet.xmlpers.api.ObjectDao;
|
||||
import ch.eitchnet.xmlpers.api.PersistenceConstants;
|
||||
import ch.eitchnet.xmlpers.api.PersistenceTransaction;
|
||||
import ch.eitchnet.xmlpers.api.XmlPersistenceException;
|
||||
import ch.eitchnet.xmlpers.objref.IdOfSubTypeRef;
|
||||
import ch.eitchnet.xmlpers.objref.ObjectRef;
|
||||
import ch.eitchnet.xmlpers.objref.SubTypeRef;
|
||||
|
@ -55,6 +60,9 @@ import ch.eitchnet.xmlpers.test.model.Resource;
|
|||
*/
|
||||
public class ObjectDaoResourceTest extends AbstractPersistenceTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private static final String BASEPATH = "target/db/ObjectDaoTest/"; //$NON-NLS-1$
|
||||
|
||||
@BeforeClass
|
||||
|
@ -226,4 +234,130 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
|
|||
assertNull("Expected that resource was deleted by ID, thus can not be read anymore", resource); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailModifyNotExisting() {
|
||||
setup(IoMode.SAX);
|
||||
|
||||
this.thrown.expect(XmlPersistenceException.class);
|
||||
this.thrown.expectMessage(containsString("Persistence unit does not exist for")); //$NON-NLS-1$
|
||||
|
||||
// update
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
Resource resource = createResource();
|
||||
tx.getObjectDao().update(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailDeleteNotExisting() {
|
||||
setup(IoMode.SAX);
|
||||
|
||||
this.thrown.expect(XmlPersistenceException.class);
|
||||
this.thrown.expectMessage(containsString("Persistence unit does not exist for")); //$NON-NLS-1$
|
||||
|
||||
// delete
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
Resource resource = createResource();
|
||||
tx.getObjectDao().remove(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAllowAllOperationsInSameTx() {
|
||||
setup(IoMode.SAX);
|
||||
|
||||
String subType = ModelBuilder.RES_TYPE;
|
||||
String name = "shouldPersistById "; //$NON-NLS-1$
|
||||
|
||||
// create
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
String id = "shouldAllowAllOperationsInSameTx_create"; //$NON-NLS-1$
|
||||
Resource resource = createResource(id, name, subType);
|
||||
|
||||
tx.getObjectDao().add(resource);
|
||||
}
|
||||
|
||||
// create / modify
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
String id = "shouldAllowAllOperationsInSameTx_create_modify"; //$NON-NLS-1$
|
||||
Resource resource = createResource(id, name, subType);
|
||||
|
||||
tx.getObjectDao().add(resource);
|
||||
tx.getObjectDao().update(resource);
|
||||
}
|
||||
|
||||
// create / delete
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
String id = "shouldAllowAllOperationsInSameTx_create_delete"; //$NON-NLS-1$
|
||||
Resource resource = createResource(id, name, subType);
|
||||
|
||||
tx.getObjectDao().add(resource);
|
||||
tx.getObjectDao().remove(resource);
|
||||
}
|
||||
|
||||
// create / modify / delete
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
String id = "shouldAllowAllOperationsInSameTx_create_modify_delete"; //$NON-NLS-1$
|
||||
Resource resource = createResource(id, name, subType);
|
||||
|
||||
tx.getObjectDao().add(resource);
|
||||
tx.getObjectDao().update(resource);
|
||||
tx.getObjectDao().remove(resource);
|
||||
}
|
||||
|
||||
String id = "shouldAllowAllOperationsInSameTx_read_modify"; //$NON-NLS-1$
|
||||
|
||||
// prepare for read/modify
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
Resource resource = createResource(id, name, subType);
|
||||
tx.getObjectDao().add(resource);
|
||||
}
|
||||
|
||||
// read / modify
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
|
||||
Object resource = tx.getObjectDao().queryById(objectRef);
|
||||
assertNotNull(resource);
|
||||
tx.getObjectDao().update(resource);
|
||||
}
|
||||
|
||||
// read / delete
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
|
||||
Object resource = tx.getObjectDao().queryById(objectRef);
|
||||
assertNotNull(resource);
|
||||
tx.getObjectDao().remove(resource);
|
||||
}
|
||||
|
||||
// make sure deleted, then recreate
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
|
||||
Object resource = tx.getObjectDao().queryById(objectRef);
|
||||
assertNull(resource);
|
||||
|
||||
// recreate
|
||||
resource = createResource(id, name, subType);
|
||||
tx.getObjectDao().add(resource);
|
||||
}
|
||||
|
||||
// read / modify / delete
|
||||
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
|
||||
|
||||
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
|
||||
Object resource = tx.getObjectDao().queryById(objectRef);
|
||||
assertNotNull(resource);
|
||||
tx.getObjectDao().update(resource);
|
||||
tx.getObjectDao().remove(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue