Subsonic ActiveRecord fails on compilation due to GUID - subsonic3

I have just downloaded subsonic 3, but when I try to compile my website, I get some errors. The errors all seem to relate to cases where I use GUIDs as foreign key.
One example is the code below, where CreatedBy is a foreign key to my membership table. I have highlighted the affected lines.
public void Add(IDataProvider provider){
**if(String.IsNullOrEmpty(this.CreatedBy))
this.CreatedBy=Environment.UserName;**
var key=KeyValue();
if(key==null){
var newKey=_repo.Add(this,provider);
this.SetKeyValue(newKey);
}else{
_repo.Add(this,provider);
}
SetIsNew(false);
OnSaved();
}
public void Add(string username){
**this.CreatedBy=username;**
Add();
}
public void Add(string username, IDataProvider provider){
**this.CreatedBy=username;**
Add(provider);
}

user514090 - wouldn't you have to create the guid from the string 1st in your model along the lines of:
this.CreatedBy = new Guid(username);
I know i had issues with guids before and tackled it in a way 'similar' to this.

Related

Create company in unit test

I have a unit-test in which I need to create a company and create/write data in that companys context. However it seems the company gets created, but I can't change my context.
i use this method to create the company:
private void CreateCompany(str companyName, str companyDisplayName, str countryRegion)
{
var model = new OMNewLegalEntityViewModel();
model.parmCompany(companyName);
model.parmName(companyDisplayName);
model.parmCountryRegion(countryRegion);
model.createLegalEntity();
}
And i check if a company exists with this method:
public boolean CompanyExists(str company)
{
CompanyInfo companyInfo;
select firstonly * from companyInfo
where companyInfo.DataArea == company;
if(companyInfo)
{
return true;
}
//fallback
return false;
}
The following is a shortened version of what is happening in my test method:
if(!this.CompanyExists('XXX'))
{
this.CreateCompany('XXX','XXX','DEU');
boolean companyCreated = this.CompanyExists('XXX');
this.assertTrue(companyCreated);
}
changecompany('XXX')
{
//do something
}
The changecompany throws an error that the company does not exist.
Am I missing something crucial?
I was able to test your given code without problems using the newest update of Dynamics Operations installed. Maybe try updating your system if not already done and check if that helps.
Version in use:
Platform build: 7.0.5286.41360
Platform version: Update27
Product build: 10.0.107.20005
Product version: 10

How to remove a many-to-many relationship with spring-data-neo4j?

I have the following entities:
#NodeEntity(label = "A")
public class A {
#Property(name = "something")
private String someProperty;
//... getters and setters
}
#NodeEntity(label = "B")
public class B {
#Property(name = "someOtherThing")
private String otherProperty;
//... getters and setters
}
#RelationshipEntity(type = "AB")
public class AB {
#StartNode
private A start;
#EndNode
private B end;
#Property(name = "evenOtherThing")
private String prop;
//... getters and setters
}
So, in this situation I have (:A)-[:AB]->(:B). I can have several ABs (meaning I can connect A to B several times, having different properties each time).
With that configuration I can save AB instances without problems, but when it comes to deleting just the relationship, I couldn't find a way to do so, using the spring-data-neo4j methods.
Things that I tried:
1- Custom query:
#Repository
public interface ABRepository extends GraphRepository<AB> {
#Query("MATCH (a:A)-[ab:AB]->(b:B) WHERE a.something={something} DELETE ab")
void deleteBySomething(#Param("something") String something);
}
Usage:
#Autowired
ABRepository repository;
//...
repository.deleteBySomething(something);
It didn't work as expected. The A node is removed altogether with the AB relationship. If I run the query directly at the database, it works as expected.
2- Delete from the repository:
#Repository
public interface ABRepository extends GraphRepository<AB> {
#Query("MATCH (a:A)-[ab:AB]->(b:B) WHERE a.something={something} RETURN a,ab,b")
Iterable<AB> findBySomething(#Param("something") String something);
}
Usage:
Iterable<AB> it = repository.findBySomething(something);
repository.delete(it);
Same stuff. The nodes are removed. I tried to iterate over the Iterable<AB> and remove the relationships one by one, without success as well.
3- Nulling the references of A and B inside AB and saving AB:
Same code of the repository, with a different usage:
Iterable<AB> it = repository.findBySomething(something);
for (AB ab : it) {
ab.setA(null);
ab.setB(null);
}
repository.save(it);
Here I'm just trying random stuff. It didn't work as expected. The framework rises an exception stating that the start and end nodes can't be null.
So, what am I doing wrong? What does it take to remove a simple relationship from the database using spring-data-neo4j, without removing the linking nodes?
For the record: my neo4j database is v.3.0.4 and my spring-data-neo4j is v.4.1.4.RELEASE. Running Java 8.
In the end the problem was a sum of two factors.
First: not mentioned in the question, but the way I saved the AB entity wasn't ideal. I was using repository.save(ab) directly, and that can make the framework do some magic with the A and B entities inside. To save just the relationship, without touching the related entities, the repository.save(ab, 0) should be used.
Second: removing entities using a custom query is intuitively faster than fetching the entities and then removing them, so using that approach was my first goal. And here again I was confused by some magic behind the scenes, better described at this question: Spring Data Neo4j 4returning cached results?
In summary, after removing entities or relationships using custom queries, I should clear the session:
#Autowired
Session session;
//...
repository.deleteBySomething(something);
session.clear();
These two tweaks fixed the weird behavior I was having with the framework.

SDN 2.1.0/neo4j 1.8: java.lang.IllegalArgumentException: Cannot obtain single field value for field 'schoolRef'

I am able add and save multiple SchoolRef, but am getting the error after retrieving the (ancestor and eagerly fetching the) Education object and then attempting to add another SchoolRef. This was working with SDN 2.0.1, but I've also changed other things, including the Repository/Cypher query below, so I can't isolate it to the upgrade.
#Fetch #RelatedTo(type = "EDUCATION_HAS_SCHOOLREF")
private Set<SchoolRef> schoolRefs = new HashSet<SchoolRef>();
public Education() {
}
public void addSchoolRef(SchoolRef schoolRef) {
getSchoolRefs().add(schoolRef);
}
Repository:
public interface UserRepository extends GraphRepository<User>, CypherDslRepository<User> {
#Query("start id=node:Identifier(identifier={0}) match id<-[:USER_HAS_IDENTIFIER]-user return user")
public User findById(String id);
Stacktrace:
Caused by: java.lang.IllegalArgumentException: Cannot obtain single field value for field 'schoolRef'
at org.springframework.data.neo4j.fieldaccess.RelatedToSingleFieldAccessorFactory$RelatedToSingleFieldAccessor.getValue(RelatedToSingleFieldAccessorFactory.java:94)
at org.springframework.data.neo4j.fieldaccess.DefaultEntityState.getValue(DefaultEntityState.java:97)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:90)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$000(SourceStateTransmitter.java:40)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$2.doWithAssociation(SourceStateTransmitter.java:61)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:207)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:57)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:100)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:92)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
at org.springframework.data.neo4j.support.Neo4jTemplate.createEntityFromState(Neo4jTemplate.java:180)
at org.springframework.data.neo4j.fieldaccess.RelationshipHelper.createEntitySetFromRelationshipEndNodes(RelationshipHelper.java:130)
at org.springframework.data.neo4j.fieldaccess.RelatedToFieldAccessor.createEntitySetFromRelationshipEndNodes(RelatedToFieldAccessor.java:86)
at org.springframework.data.neo4j.fieldaccess.RelatedToSingleFieldAccessorFactory$RelatedToSingleFieldAccessor.getValue(RelatedToSingleFieldAccessorFactory.java:76)
at org.springframework.data.neo4j.fieldaccess.DefaultEntityState.getValue(DefaultEntityState.java:97)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:90)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$000(SourceStateTransmitter.java:40)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$2.doWithAssociation(SourceStateTransmitter.java:61)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:207)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:57)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:100)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:92)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:244)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:293)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:287)
at org.springframework.data.neo4j.fieldaccess.RelationshipHelper.getOrCreateState(RelationshipHelper.java:119)
at org.springframework.data.neo4j.fieldaccess.RelationshipHelper.createSetOfTargetNodes(RelationshipHelper.java:111)
at org.springframework.data.neo4j.fieldaccess.RelatedToFieldAccessor.createSetOfTargetNodes(RelatedToFieldAccessor.java:82)
at org.springframework.data.neo4j.fieldaccess.RelatedToCollectionFieldAccessorFactory$RelatedToCollectionFieldAccessor.setValue(RelatedToCollectionFieldAccessorFactory.java:66)
at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.updateValue(ManagedFieldAccessorSet.java:94)
at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.update(ManagedFieldAccessorSet.java:82)
at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.add(ManagedFieldAccessorSet.java:108)
---- Edit:
Same error, but under different circumstances..
School school = new School();
school = neo4j.repositoryFor(School.class).save(school);
User user1 = new User("Junit", "1");
SchoolRef schoolRef1 = new SchoolRef();
schoolRef1.setSchool(school);
user1.addSchoolRef(schoolRef1);
user1 = neo4j.repositoryFor(User.class).save(user1);
User user2 = new User("Junit", "2");
SchoolRef schoolRef2 = new SchoolRef();
schoolRef2.setSchool(school);
user2.addSchoolRef(schoolRef2);
user2 = neo4j.repositoryFor(User.class).save(user2); // <- error here
sometimes I can be blind to the obvious problem...
In my case, SchoolRef references a single school, but schools can have many schoolRefs. I had incorrectly implemented School with a single reference back to SchoolRef.
I was able to create multiple SchoolRefs which referenced a single School, but got this error when I tried to fetch a School which had the multiple references.
We ran into this issue as well, but it was due to having a separate relationship with the same label.

What is ScaffoldColumn and RegularExpression attributes

I am trying to learn MVC4 and i've come to this chapter called validation.
I came to know about DataAnnotations and they have pretty neat attributes to do some server side validation. In book they have only explained about [Required] and [Datatype] attribute. However in asp.net website i saw something called ScaffoldColumn and RegularExpression.
Can someone explain what they are, even though I know little what RegularExpression does.
Also are there any other important validation attributes I should know?
Scaffold Column dictates if when adding a view based on that datamodel it should/not scaffold the column. So forexample your model's id field is a good candidate for you to specify ScaffoldColumn(false), and other foreign key fields etc.
I you specify a regular expression, then if you scaffold a new view for that model,edit customer for example, a regex or regular expression on field will enforce that entered data must match that format.
You can read about ScaffoldColumnAttribute Class here
[MetadataType(typeof(ProductMetadata))]
public partial class Product
{
}
public class ProductMetadata
{
[ScaffoldColumn(true)]
public object ProductID;
[ScaffoldColumn(false)]
public object ThumbnailPhotoFileName;
}
And about RegularExpressionAttribute Class you can read here.
using System;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(CustomerMetaData))]
public partial class Customer
{
}
public class CustomerMetaData
{
// Allow up to 40 uppercase and lowercase
// characters. Use custom error.
[RegularExpression(#"^[a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Characters are not allowed.")]
public object FirstName;
// Allow up to 40 uppercase and lowercase
// characters. Use standard error.
[RegularExpression(#"^[a-zA-Z''-'\s]{1,40}$")]
public object LastName;
}

SQLite unit testing NHibernate generated cascade relationships

The following is some background info on this post. You can just skip to the question if you like:
In this excellent article (http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx) the author contends that "When using NHibernate we generally want to test only three things:
1) that properties are persisted,
2) that cascade works as expected
3) that queries return the correct result.
-) that mapping is complete & correct (implied)
My take is that he goes on to say that SQLite can and should be the unit test tool of choice to do all of the above. It should be noted that the author seems to be one of more experienced and skilled NHib developers out there, and though he doesn't expressly say so in the article, he implies in a question later that the domain can and should be handling some of SQLite's shortcomings.
QUESTION:
How do you use SQLite to test cascade relationships, especially given that it does not check foreign key constraints. How do you test your model to make sure foreign key constraints will not be a db issue.
Here are some units tests I came up with to test cascade behavior. The model is simply a Department that can have zero to many StaffMembers, with cascade set to NONE.
[Test]
public void CascadeSaveIsNone_NewDepartmentWithFetchedStaff_CanSaveDepartment()
{
_newDept.AddStaff(_fetchedStaff);
Assert.That(_newDept.IsTransient(), Is.True);
_reposDept.SaveOrUpdate(_newDept);
_reposDept.DbContext.CommitChanges();
Assert.That(_newDept.IsTransient(), Is.False);
}
[Test]
public void CascadeSaveIsNone_NewDepartmentWithFetchedStaff_CannotSaveNewStaff()
{
_newDept.AddStaff(_newStaff);
Assert.That(_newDept.IsTransient(), Is.True);
Assert.That(_newStaff.IsTransient(), Is.True);
_reposDept.SaveOrUpdate(_newDept);
_reposDept.DbContext.CommitChanges();
Assert.That(_newDept.IsTransient(), Is.False);
Assert.That(_newStaff.IsTransient(), Is.True);
}
[Test]
public void CascadeDeleteIsNone_FetchedDepartmentWithFetchedStaff_Error()
{
_fetchedDept.AddStaff(_fetchedStaff);
_reposDept.SaveOrUpdate(_fetchedDept);
_reposStaff.DbContext.CommitChanges();
_reposDept.Delete(_fetchedDept);
var ex = Assert.Throws<GenericADOException>(() => _reposDept.DbContext.CommitChanges());
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("could not delete:"));
Console.WriteLine(ex.InnerException.Message);
Assert.That(ex.InnerException.Message, Text.Contains("The DELETE statement conflicted with the REFERENCE constraint"));
}
[Test]
public void Nullable_NewDepartmentWithNoStaff_CanSaveDepartment()
{
Assert.That(_newDept.Staff.Count(), Is.EqualTo(0));
var fetched = _reposDept.SaveOrUpdate(_newDept);
Assert.That(fetched.IsTransient(), Is.EqualTo(false));
Assert.That(fetched.Staff.Count(), Is.EqualTo(0));
}
The third test, ".._FetchedDepartmentWithFetchedStaff_Error" works against Sql Server, but not SQLite since the latter does not check foreign key constraints.
Here are tests for the other side of the relationship; a StaffMember can have one Department, with cascade set to NONE.
[Test]
public void CascadeSaveIsNone_NewStaffWithFetchedDepartment_CanSaveStaff()
{
_newStaff.Department = _fetchedDept;
_reposStaff.SaveOrUpdate(_newStaff);
_reposStaff.DbContext.CommitChanges();
Assert.That(_newStaff.Id, Is.GreaterThan(0));
}
[Test]
public void CascadeSaveIsNone_NewStaffWithNewDepartment_Error()
{
_newStaff.Department = _newDept;
Assert.That(_newStaff.IsTransient(), Is.True);
var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff));
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("not-null property references a null or transient value"));
}
[Test]
public void CascadeDeleteIsNone_FetchedStaffWithFetchedDepartment_DeletesTheStaff_DoesNotDeleteTheDepartment()
{
_newStaff.Department = _fetchedDept;
_reposStaff.SaveOrUpdate(_newStaff);
_reposStaff.DbContext.CommitChanges();
_reposStaff.Delete(_newStaff);
Assert.That(_reposStaff.Get(_newStaff.Id), Is.Null);
Assert.That(_reposDept.Get(_fetchedDept.Id), Is.EqualTo(_fetchedDept));
}
[Test]
public void NotNullable_NewStaffWithUnknownDepartment_Error()
{
var noDept = new Department("no department");
_newStaff.Department = noDept;
var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff));
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("not-null property references a null or transient"));
}
[Test]
public void NotNullable_NewStaffWithNullDepartment_Error()
{
var noDept = new Department("no department");
_newStaff.Department = noDept;
var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff));
Console.WriteLine(ex.Message);
Assert.That(ex.Message, Text.Contains("not-null property references a null or transient"));
}
These tests succed against Sql Server and SQLite. Can I trust the SQLite tests? Are these worthwhile tests?
Cheers,
Berryl
As i understand the article it is about testing the NHibernate Mapping. In my opinion this has nothing to do with db related issues but with testing the nhibernate attributes you set in your mapping. There is no need to assert that it is not possible to create invalid data: you only have to proof that your code creates the desired result and/or checks the things you want to check. You can test cascade, cascade-delete and delete-orphan. whatever you want the way you do it in the tests working with sqlite. But the third test tries to test the constraint, which is nothing nhibernate worries about.
If you want to test your Db contraints you should indeed use your production db and not sqlite. You could do it with or without hibernate but this has nothing to do with your mapping.
If you on the other hand really want a workarround for your Foreign Key tests with SQLite you could try to use this foreign_key_trigger_generator. I haven't tried but it seems to generate before-insert-triggers that assure the existance of the referenced Pk.
Maybe you could write a comment wheather this tool is usefull.