GAE JDO: default fetch group member null on second read - google-app-engine

I have a persistable class like this:
#PersistenceCapable(detachable = "true")
public class MyClass {
...
#Persistent(defaultFetchGroup = "true")
#Element(dependent = "true")
private Set<Key> mySet = new HashSet<Key>();
...
}
Which I first persist and then read back like so:
pm.getFetchPlan().setGroup(FetchPlan.DEFAULT);
pm.getFetchPlan().setMaxFetchDepth(1);
myInstance = pm.getObjectById(MyClass.class, key);
What's bizarre is that this works fine the first time after a server restart. However, the second time I make the query, mySet remains null.
I have been trying the same with an ArrayList, but no luck. I'm completely clueless as to what might cause behaviour like this, so any vague pointers as to what may be the cause would be greatly appreciated.
Update:
I found a fix, but I don't understand why it works. If I add a copy constructor for User and copy the instance after the read, it works consistently. I would assume that there's a cache that always hands me back the same instance, but stepping through the program, I can't find any code that would set roles to null. Is this likely to be a side effect I'm overlooking or is there a more fundamental issue that I'm not understanding?

Related

How to create a read-only array in java?

I want to get rid of clone() method.
For the below class sonar (static code check tool) was complaining that
I should not directly expose an internal array of the object as one can change the array after the method call which in turn changes the object's state. It suggested to do a clone() of that array before returning so that object's state is not changed.
Below is my class...
class DevicePlatformAggregator implements IPlatformListings{
private DevicePlatform[] platforms = null;
public DevicePlatform[] getAllPlatforms() throws DevicePlatformNotFoundException {
if (null != platforms) {
return platforms.clone();
}
List<DevicePlatform> platformlist = new ArrayList<DevicePlatform>();
..... // code that populates platformlist
platforms = platformlist.toArray(new DevicePlatform[platformlist.size()]);
return platforms;
}
}
However I don't think its good to clone as its unnecessary to duplicate the data.
There is nothing similar to Collections.unmodifiableList() for array
I can not change the return type of the method getAllPlatforms() to some
collection as it is an interface method
I am not a Java guru but I am pretty confident that you are out of luck here. There is no way to make a primitive array immutable apart from creating an array of 0 elements.
Making it final won't help cause only the reference pointing to it would be immutable.
As you already said the way to go in obtaining an unmodifiable list would be to use Collections as in the following example:
List<Integer> contentcannotbemodified= Collections.unmodifiableList(Arrays.asList(13,1,8,6));
Hope it helps.

RegisterMultiple does not keep implementation type as singleton if registered as multiple registration types?

I am trying to add a type called TypeA as two different registration types: InterfaceA and InterfaceB.
container.RegisterMultiple(typeof(InterfaceA), new[] {typeof(TypeA), typeof(TypeB)});
container.RegisterMultiple(typeof(InterfaceB), new[] {typeof(TypeA), typeof(TypeC)});
But when I Resolve them, I get one instance of TypeA when resolving InterfaceA, and another instance when resolving InterfaceB. I expect to get the same instance for both resolves, but I am not.
I have also tried to add .AsSingleton() to the call, but it made no difference.
Am I doing something wrong, or does anyone have any ideas of doing this without adding a TypeAFactory or such that keeps track of the instances instead?
Thanks in advance for any help.
I think what you are seeing is by design.
To get the same instance for both interfaces you can create the instance yourself and register it for both interfaces:
var instanceOfA = new TypeA(...);
container.Register<InterfaceA>(instanceOfA);
container.Register<InterfaceB>(instanceOfA);
I solved this on my own with a quite ugly (but yet quite elegant) solution.
I create another, internal, instance of a TinyIoCContainer, and I register all my types with the actual TinyIoCContainer.Current by giving it a factory in the form of:
var container = TinyIoCContainer.Current;
var internalIoC = new TinyIoCContainer();
Dictionary<Type, Object> instances = new Dictionary<Type, Object>();
...
Func<TinyIoCContainer, NamedParameterOverloads, Object> factory = (TinyIoCContainer c, NamedParameterOverloads o) =>
{
if (instances.ContainsKey(implementationType) == false)
{
// Create the instance only once, and save it to our dictionary.
// This way we can get singleton implementations of multi-registered types.
instances.Add(implementationType, internalIoC.Resolve(implementationType));
}
return instances[implementationType];
};
container.Register(registerType, factory, implementationType.FullName);
I'm sure there will be a few caveats with this solution, but I'm also sure I'll be able to figure out a workable fix for them, as things look right now.

JCR, JackRabbit : Making XPath for search for a Year of a Date and for subnodes properties values

Grettings!.
I am having too much troubling with the following question... i will try to be as clear as possibly.
Currently i have a Jackrabbit JCR implementation running in our web application. All things works fine, buts just a little (big) problem appears when trying to do some specific search.
For a brief synopsis of what kind of data is stored, we have 3 a node class called "Entry", that extends another node class named "BaseEntry" and that extends another called "BaseNode".
The Entry class represents a Node in our JCR system, and has a set of properties (mapped as attributes in the corresponding class), an also inherits the properties mapped in their superclasses as well.
I copy and paste, the important part of the class definition and the properties of interest...
#Node(jcrType = "entry", extend = BaseEntry.class)
public class Entry extends BaseEntry {
... // nothing really important here
}
#Node(jcrType = "baseEntry", extend = BaseNode.class, isAbstract = true)
public abstract class BaseEntry extends BaseNode {
#Collection (jcrType = "attachment",
collectionConverter = NTCollectionConverterImpl.class)
protected List<Attachment> attachments = new ArrayList<Attachment>();
...
}
#Node(jcrType = "baseNode", isAbstract = true)
public abstract class BaseNode {
#Field(jcrName = "name", id = true)
protected String name;
#Field(jcrName = "creationDate")
protected Date creationDate;
...
}
1) How i can make a predicate for select only those nodes (entries) that have a specific year in the property creationDate ignoring the rest. The attribute is of type Date (in the class) and i guess the property is stored in a xs:DateTime format i guess... i really do not know very well... how it really match a Date in the JCR underlying system.
So far i get to this...
there must something like this //element(*, entry)[getYear(#creationDate) == <year>]
must be an integer, string, ... i really don't kwow.
2) How i can make a predicate for select only those nodes (entries) that contains attachments that have name a certain name.
Again the class Attachment, the important part...
#Node(jcrType = "attachment", discriminator = true)
public class Attachment extends BaseNode implements Comparable<Attachment> {
...
}
So far i get to this.. that is working.. but there must be a better way:
//element(*, entry) [jcr:contains(./*,'<nameOfInterest>')]
That all friends, i really apologies for the absent of information that i reader may require to understand better the background of the matter, i guess this is what i can do. I am pretty new to Jackrabbit and JCR, and i have to get the hands (dirty) on it, without knowing very well what i am doing.. and obliviously it began to be very complicated...
Well hope any charity soul can answer this, and help, at least a little :D.
Thanks for advance.
Greetings.
Víctor.
I'm not an expert, but I try to answer anyway:
Question 1
//element(*, entry)[getYear(#creationDate) == <year>]
I think you could use:
//element(*, entry)[
#creationDate >= '2001-01-01T00:00:00.0'
and #creationDate < '2002-01-01T00:00:00.0']
Question 2
Select only those nodes (entries) that contains attachments that have name a certain name.
I only know the SQL-2 query, using equality on the node name. I'm not sure if this is what you are looking for:
select * from [nt:base] where name() = '<nameOfInterest>'

ListDataModel not serializable==won´t run on GAE

Ok so I am really stuck now. I have a h:datatable and the only way to get the row details seems to be DataModel#getRowData(). Unfortunately ListDataModel which is needed to wrap the necessary data is NOT serializable so will not work on GAE, and I really need it to work! Does anyone have any idea about any workaround or some way to make it function.
Help much appreciated!
Mark the property transient (so that it will be skipped during serialization) and introduce lazy loading in the getter.
E.g.
private List<Item> itemList;
private transient DataModel<Item> itemModel;
public DataModel<Item> getItemModel() {
if (itemModel == null) {
itemModel = new ListDataModel<Item>(itemList);
}
return itemModel;
}
There are by the way alternate ways to retrieve the current row. See also How can I pass selected row to commandLink inside dataTable?

Google App Engine - JDODetachedFieldAccessException

I'm pretty new to JPA/JDO and the whole objectdb world.
I have an entity with a set of strings, looks a bit like:
#Entity
public class Foo{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Key id;
private Set<String> bars;
public void setBars(Set<String> newBars){
if(this.bars == null)
this.bars = new HashSet<String>;
this.bars = newBars;
}
public Set<String> getBars(){
return this.bars;
}
public void addBar(String bar){
if(this.bars == null)
this.bars = new HashSet<String>;
this.bars.add(bar);
}
}
Now, in another part of the code, I'm trying to do something like this:
EntityManager em = EMF.get().createEntityManager();
Foo myFoo = em.find(Foo.class, fooKey);
em.getTransaction().begin();
myFoo.addBar(newBar);
em.merge(myFoo);
em.getTransaction().commit();
When, of course, newBar is a String.
But, what I get is:
javax.jdo.JDODetachedFieldAccessException: You have just attempted to access field "bars" yet this field was not detached when you detached the object. Either dont access this field, or detach it when detaching the object.
I've searched for an answer, but I couldn't find one.
I've seen someone ask about a Set of strings, and he was told to add an #ElementCollection notation.
I tried that, but I got an error about the String class Metadata (I don't really understand what it means.)
I would really appreciate some help on this thing, even a good reference to someone explaining this (in simple English).
OK,
So I found the answer in some blog.
So for anyone who's interested:
In order to use a Collection of simple data types (in JPA), a
#Basic
notation should be added to the collection. So from my example at the top, It should've been written:
#Basic
private Set<String> bars;
So you are using JPA, right? (I see EntityManager rather than JDO's PersistenceManager.) Since you are getting a JDO error, I suspect that your app isn't configured properly for JPA.
JPA docs: http://code.google.com/appengine/docs/java/datastore/jpa/overview.html
JDO docs: http://code.google.com/appengine/docs/java/datastore/jdo/overview.html
You need to pick one datastore wrapper and stick with it. The default new app with the Eclipse tools is configured for JDO, and it is a reasonable choice, but you'll have to change your annotations around a little bit.

Resources