I've got a domain called Planning that has a hasMany of another domain called Employee included in it. I'm trying to do a findAll of these plannings where the plannings contain a particular employee and I can't get it to work.
I'm trying to do it like so, my print statements do print the contains as true
plannings = plannings.findAll{planning->
if(employee) {
log.info("find plannings with employee ${employee} ${planning.employees.contains(employee)}")
planning.employees.contains(employee)
}
}
I'm not doing this as a Hibernate query as this broke the application in another weird way. This code is executed in a for each and for whatever reason that causes some weird behavior with Hibernate.
The closure must return a boolean value - see http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Collection.html#findAll(groovy.lang.Closure)
This should work (not tested):
plannings = plannings.findAll{planning-> planning.employees?.contains(employee)}
BTW: I wouldn't assign the filtered list to the origin plannings list. Extract a a new expressive variable like planingsOfEmployee or something similar.
Without more relevant details around your problem (what's the weird behavior? log traces? hibernate mappings?, etc.) all we can do is to speculate; and if I have to do so, I would say that most likely:
The employee object you are using for comparison is a detached one.
The employee object does not override meaningfully equals and hashCode
You use using this detached employee to do comparisons against against persisted employees (using planning.employees.contains(employee)) found inside planning
Under these circumstances the comparisons will never be true even when they may represent the same objects. If this is your case, you must either:
Use a persisted employee object to do the comparisons.
Or, implement equals and hashCode semantically meaningful for Employee
Hope this helps.
Related
I have a Neo4j/OGM Entity Person which I mapped to the Label User using
#NodeEntity(label="User).
I now want to write a custom Query MATCH (p:Person) where....
As far as I see, there is no way to use my Application-Side Type Person instead of the Graph-Side Label User like in Hibernate, right?
If there is a way, please explain how to do this, or tell my a key-word to google for.
Same question goes for entity properties.
Thank you.
Update:
Lets say I have a User class like so:
#NodeEntity(label="Person")
class User {
#Property(name="username")
private String name;
...
}
I've used the Mapping to obtain loose coupling so I can eg. rename the Person and won't affect the Neo4j.
And in the Neo4j there are for example Houses with Relationships to Users.
Now I want to load all Houses, referencing a User with the name "Sven", so the Statement would be MATCH (h:House)-[:HOLDS]->(p:Person {username:'Sven'}).
Given, that I might have a huge poject with all the entities in some submodule somewhere else, I might not know, that User is mapped to Person and the user.name is mapped to username, so in a Hibernate environment, I would query as MATCH (h:House)-[:HOLDS]->(u:User {name:'Sven'}). However in OGM this doesn't seem to work.
There might be a way to solve this architectually but in some projects you don't have this choise.
So the question in the End is: Is there some way to get this to work, or do I really need to know the mapping of every entity i use?
You can do this in several ways :
Make your User extend a Person class
if you need more dynamic labels, the class can contain an #Labelsannotated list of labels to apply. See the documentation for more details
About properties, I don't see how this would be useful. Interested to hear about the use case.
Im trying to find out which attributes of an entity have been changed.
As far I have seen, there is a PersistenceSession with a method to check an object if an attribute isDirty. But its always true because it never registers the old object.
So if I take the demo from the QuickGuide and override the update method in the CoffeeBeanRepository:
/**
* #param \Acme\Demo\Domain\Model\CoffeeBean $coffeeBean
*/
public function update($coffeeBean) {
\TYPO3\Flow\var_dump($this->persistenceSession->isDirty($coffeeBean, 'name'), "name changed before");
parent::update($coffeeBean);
\TYPO3\Flow\var_dump($this->persistenceSession->isDirty($coffeeBean, 'name'), "name changed after");
}
... its always TRUE (both), despite I didn't change anything.
Anyone an idea/reference how this can be accomplished?
I am using it for a REST API where a user can't update several fields and on editing of some fields additional actions have to be executed.
The persistenceSession is part of the generic persistence backend of Flow and is neither maintained, nor really used unless you explicitly deactivate doctrine. Hence persistenceSession will not help you, because all entities are considered new for the persistenceSession as you noticed.
With doctrine you need to get the entity changeset from the "UnitOfWork", which you can get from an injected \Doctrine\Common\Persistence\ObjectManager. See also Is there a built-in way to get all of the changed/updated fields in a Doctrine 2 entity
However, this is a suboptimal solution and a hacky work-around at best. If you need to track changes to your entity, it should be an explicit part of your domain model. For example make your setters record a changed properties list, when the given value is different from the current.
When done, you could even optimize doctrines change tracking on the way with that: http://doctrine-orm.readthedocs.org/en/latest/reference/change-tracking-policies.html#notify
I have an aggregated data view in an MVC project which displays the totals per month broken down by audit status. The controller code sets this up using a simple LINQ projection into an anonymous object like this:
From audits In db.Audits
Group By key = audits.DateCreated.Value.Month Into g = Group
Select New With {
.Month = key,
.Assigned = g.Sum(AuditsWithStatus(AuditStatus.Issued)),
.Unassigned = g.Sum(AuditsWithStatus(AuditStatus.Pending)),
.Closed = g.Sum(AuditsWithStatus(AuditStatus.Closed)),
.Cancelled = g.Sum(AuditsWithStatus(AuditStatus.Cancelled))
}
I know this is one of the big advantages of LINQ (using anonymous types), but I don't like losing the strong typing in the view (ie #ModelType SomeStrongType). Is there any general advice on this? Articles, blogs, or other places that deal with the issue and when to use which?
You cannot do anything with anonymous types outside of the scope of your method. You cannot return them to your view for example. In those cases you have to use a known type.
I use anonymous types when I am selecting data that I am then processing in another way. For example, selecting some bespoke data out of 1 source using Linq, and putting to put into another source.
If you are returning aggregate data such as an IEnumerable<IGrouping<TKey, TValue>> and TKey and TValue are anonymous types (you can group by anonymous types if you want); then you would not want to create 2 classes for TKey and TValue, where TKey has an overridden Equals and GetHashCode so you can group by it. And then do nothing more than read some values from it and throw it away, never to be re-used.
TLDR; use them when there is no need to create a known type to store your results. If you need to pass your results to somewhere outside the scope of the method, then you will need a type.
General advice is simple: always create dedicated viewmodel type for your views. In your case it would be pretty simple, containing exactly the properties you have in you anonymous class.
I understand that it seems like an unneeded overhead, but it'll make your code more readable and verifiable.
Suppose I have a domain class branch which has several members:
…
static hasMany = [ members:Member ];
…
Now suppose I want to have the number of members of that branch readily available, to have it displayed in the list and view actions, so perhaps storing that information into a variable in the domain class itself would be a good idea?
…
Integer memberCount = members.size();
static constraints = {
memberCount(editable:false);
}
…
(Is this the correct syntax?) Edit: This is not the correct syntax. I cannot assess the size of the members list, as it doesn’t exist yet and grails will complain about size() not being applicable to null objects. What else could I try?
However, as memberCount is now a variable in the domain class, it is possible to assign a value to it upon creation of the Branch (which is contra-intuitive) and it will not be updated automatically once a new Member is added.
It is of course possible to reach the desired result in a different way. I could manipulate the view.gsp and list.gsp in the /Branch directory, add some additional <td>s there etc. But that does not seem very elegant to me.
Basically, I think what I am looking for is some way to tell grails that a certain variable is derived, should not be setable by the user, but update whenever necessary. Is there such way?
You can add any property you don't want persisted to the transients static list:
static transients = ['memberCount']
See this page in the manual
Also, this StackOverflow question answers the same question
Also, a better way to do derived properties may be to use the Derived Properties feature of GORM
Is it a bad practice to use domain objects in Sets or as keys in Maps?
In the past I've done things like this a lot
Set<Book> someBooks = [] as Set
someBooks.addAll (Book.findAllByAuthorLike('%hofstadter%'))
someBooks.add (Book.findByTitleLike ('%eternal%'))
However I have noticed that I often encounter problems when findAllByAuthorLike might return a list of Hibernate Proxy objects com.me.Book_$$_javassist_128 but findByTitleLike will return a proper com.me.Book object. This causes duplicates in the set because the real object and the proxy are considered not equal.
I find I need to be extremely careful when using Sets of domain objects like this, and I get the feeling it might be something I should not be doing in the first place.
The alternative is of course to use a set/map of id's, but it makes my code verbose and prone to misunderstanding
Set<Integer> someBooks = [] as Set // a set of id's for books
#Burt: I thought Grails domain classes already did this, at least so that equals/compare was done on class/id's rather than the object instance. Do you mean a special comparator for hibernate proxies?
return (this.class == obj.class && this.id == obj.id) ||
(obj.class == someHibernateProxy && this.id == obj.id)
It's not bad practice at all, but just like in a non-Grails application you should override equals and hashCode if you'll be putting them in hash-based collections (HashSet, HashMap, etc.) and also implement Comparable (which implies a compareTo method) if you're going to use TreeSet/TreeMap/etc.
Proper implementation of equals() and hashcode() in a Hibernate-backed situation is far from trivial. Java Collections require that hashcodes of objects and behaviour of equals() don't change, but the id of an object can change when it's a newly created object, and other fields can change for a wide variety of reasons. Sometimes you have a good unchangeable business id that you can use, but quite often that's not the case. And obviously default Java behaviour is also not suitable in a Hibernate situation.
The best solution I've seen is described here: http://onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html?page=2
The solution it describes is: initialize the id as soon as the object is created. Don't wait for Hibernate to assign an id. Configure Hibernate to use version to determine whether it's a new object. This way, id in unchangeable, and can be safely used for hashcode() and equals().