Is there anyway i can use the primefaces TreeNode/DefaultTreeNode class with JPA for persistence?
I'm trying to do it, but i'm completely lost.
I think I might have to implement my own TreeNode class to do that, but I did want to use primefaces class for using with the p:treeNode component.
I would not persist treenodes for since most likely the only way you can get them persisted is to have them serialized which will (99% chance) lead to problems in the future if PF changes something in the DefaultTreeNode.
More generically, I would never persist objects not from my own model!
As you can see in this example in the PF showcase you can add your own entities to the treenode when building them
TreeNode documents = new DefaultTreeNode(new Document("Documents", "-", "Folder"), root);
On selection you can get the object back by node.getData()
Related
I am new to wicket. There is a confusion in Model, ModelObject defaultModel, genericModel. I need to know the difference between ModelObject and Model, defaultModel and genericModel. Please help me to clear about it.
defaultModel[Object] and genericModel[Object] is the same object, behind the scenes.
Each Component has an IModel and this model brings an java.lang.Object inside. This is the defaultModelObject.
Some specializations of Component, like FormComponent, Form, GenericPanel, etc. use Java generics to make the user code more concrete. For this Wicket uses genericModel[Object] - it is the same Object but casted to its actual type. The casting is in Wicket code, not in the application code.
The title may seems confusing, but it's not easy to describe the question in few words. Let me explain the situation:
We have a web application project, and a calculation engine project. The web application collect user input and use the engine to generate some result, and represent to user. Both user input, engine output and other data will be persisted to DB using JPA.
The engine input and output consist of objects in tree structure, example like:
Class InputA {
String attrA1;
List<InputB> inputBs;
}
Class InputB {
String attrB1;
List<InputC> inputCs;
}
Class InputC {
String attrC1;
}
The engine output is in similar style.
The web application project handle the data persistence using JPA. We need to persist the engine input and output, as well as some other data that related to the input and output. Such data can be seem as extra fields to certain class. For example:
We want to persist extra field, so it looks like:
Class InputBx extends InputB{
String attrBx1;
}
Class InputCx extends InputC{
String attrCx1;
}
In Java OO world, this works, we can store a list of InputBx in InputA, and store a list of InputCx in InputBx because of the inheritance.
But we meet trouble when using JPA to persist the extended objects.
First of all, it requires the engine project to make their class become JPA entities. The engine was working fine by itself, it accept correct input and generate correct output. It doesn't smell good to force their model to become JPA entities when another project try to persist the model.
Second, the JPA doesn't accept the inherited objects when using InputA as the entry. From JPA point of view, it only know that InputA contains a list of InputB, and not possible to persist/retrieve a list of InputBx in object of InputA.
When trying to solve this, we had come up 2 ideas, but neither one satisfied us:
idea 1:
Use composition instead inheritance, so we still persist the original InputA and it's tree structure include InputB and InputC:
Class InputBx{
String attrBx1;
InputB inputB;
}
Class InputCx{
String attrCx1;
InputC inputC;
}
So the original input object tree can be smoothly retrieved, and InputBx and InputCx objects needs to be retrieved using the InputB and InputC objects in the tree as references.
The good thing is that no matter what changes made to the structure of the original input class tree (such as change attribute name, add/remove attributes in the classes), the extended class InputBx and InputCx and their attributes automatically synchronized.
The drawback is that this structure increases the calls to the database, and the model is not easy to use in the application(both back end and front end). Whenever we want related information of InputB or InputC, we need to manually code to search the corresponding object of InputBx and InputCx.
idea 2:
Manually make mirror classes to form a similar structure of the original input classes. So we created:
Class InputAx {
String attrA1;
List<InputBx> inputBs;
}
Class InputBx {
String attrB1;
List<InputCx> inputCs;
String attrBx1;
}
Class InputCx {
String attrC1;
String attrCx1;
}
We could use this as model of the web application, and the JPA entities as well. Here's what we could get:
Now the engine project can be set free, it doesn't need to bind to how the other projects persist these input/output objects. The engine project is independant now.
The JPA persistence works just fluent, no extra calls to database is required
The back end and front end UI just use this model to get both original input objects and related information with no effort. When trying use engine to perform calculation, we can use a mapping mechanism to transfer between the original objects and extended objects.
The drawback is also obvious:
There is duplication in the class structure, which is not desired from the OO point of view.
When considering it as DTO to reduce the database calls, it can be claimed as anti-pattern when using DTO in local transfer.
The structure is not automatically synchronized with the original model. So if there are any changes made to the original model, we need to manually update this model as well. If some developers forget to do this, there will be some not-easy-to-find defects.
I'm looking for the following help:
Is there any existing good/best practices or patterns to solve similar situation we meet? Or any anti-patterns that we should try to avoid? References to web articles are welcome.
If possible, can you comment on the idea 1 and idea 2, from the aspect of OO design, Persistence practices, your experience, ect.
I will be grateful for your help.
Briefly, I'm loading objects that descend from a base class using a repository defined against the base class. Although my objects are created with the correct descendant classes, any descendant classes that add navigation properties not present in the base class do not have those related objects loaded, and I have no way to explicitly request them.
Here is a simple method in a repository class that loads a given calendar event assuming you know its ID value:
public CalendarEvent GetEvent(int eventId)
{
using (var context = new CalendarEventDbContext(ConnectionString))
{
var result = (from evt in context.CalendarEvents
where eventId.Equals((int)evt.EventId)
select evt).ToList();
return result.ToList()[0];
}
}
CalendarEvent is a base class from which a large number of more specific classes descend. Entity Framework correctly determines the actual class of the calendar event specified by eventId and constructs and returns that derived class. This works perfectly.
Now, however, I have a descendant of CalendarEvent called ReportIssued. This object has a reference to another object called ReportRequest (another descendant of CalendarEvent, although I don't think that's important).
My problem is that when Entity Framework creates an instance of ReportIssued on my behalf I always want it to create and load the related instance of ReportRequested, but because I am creating the event in the context of generic calendar events, although I correctly get back a ReportIssued event, I cannot specify the .Include() to get the related object. I want to do it through this generically-expressed search because I won't necessarily know the type of eventId's event and also I have several other "Get" methods that return collections of CalendarEvent descendants.
I create my mappings using the Fluent API. I guess what I'm looking for is some way to express, in the mapping, that the related object is always wanted or, failing that, some kind of decorator that expresses the same concept.
I find it odd that when saving objects Entity Framework always walks the entire graph whereas it does not do the equivalent when loading objects.
I'm using DataNucleus 2 JDO implementation. I have a detached object that i must attach, BUT i don't want to attach ALL the fields (in this case, a collection)
public class Obj {
private String key;
private Collection<String> col;
}
Is there a reason why it is not possible to do this:
tx.begin();
obj.makeTransientAll(obj.getCol()); // Do not persist
pm.makePersistent(obj);
tx.commit();
or REFRESH from the database:
tx.begin();
obj.refreshAll(obj.getCol()); // Discard any changes
pm.makePersistent(obj);
tx.commit();
Thanks.
I guess you should apply your changes AFTER refreshing your object or making it transient.
Or on the other hand, do something I really wanted to do to understand more how JDO works but I didn't have much time to investigate. Why don't you after initially looking up your object, do not detach it, but keep it in attached state and modify outside the look up method, then make it persistence in another method ?
What confuses me here is that in the look up method, you'll not close your PersistenceManager and in the latter method that saves your object you'll be using another PersistenceManager which is ought to fire an exception because you are managing an object using a different PersistenceManager other than the one that looked it up on the first place.
I'm still learning about JDO and Datanucleus so please expect that my suggest may not work. And sharing your experience with my suggestion is very much appreciated.
I am very new to GWT.
I am using ext-gwt widgets.
I found many places in my office code containing like,
class A extends BaseModel{
private UserAccountDetailsDto userAccountDetailsDto = null;
//SETTER & GETTER IN BASEMODEL WAY
}
Also, the DTO reference is unused.
public class UserAccountDetailsDto implements Serializable{
private Long userId=null;
private String userName=null;
private String userAccount=null;
private String userPermissions=null;
//NORMAL SETTER & GETTER
}
Now, I am able to get the result from GWT Server side Code and things Work fine, but when I comment the DTO reference inside the class A, I am not getting any Result.
Please explain me the need of that.
Thanks
Well the problem is in implementation of GXT BaseModel and GWT-RPC serialization.
BaseModel is based around special GXT map, RpcMap. This map has defined special serialization rules, which let's avoid RPC type explosion, but as side effect, only some simple types stored in map will be serialized. E.g. you can put any type inside the map, but if you serialize/deserialize it, only values of type Integer, String ,Double,Byte, Float and Short (and arrays of this types) will be present. So the meaning behind putting reference to the DTO inside BaseModel, is to tell GWT-RPC that this type is also have to be serialized.
Detailed explanation
Basically GWT-RPC works like this:
When you define an interface for service, GWT-RPC analyzes all the classes used in parameters/ return type, to create serializers/deserializers. If you return something like Map<Object,Object> from your service, GWT-RPC will have to create a serializer for each class which implements Map and Serializable interfaces, but also it will generate serializers for each class which implements Serializable. In the end it is quite a bad situation, because the size of your compiled js file will be much biggger. This situation is called GWT-RPC type explosion.
So, in the BaseModel, all values are stored in RpcMap. And RpcMap has custom written serializer (RpcMap_CustomFieldSerializer you can see it's code if you interested how to create such things), so it doesn't cause the problem described above. But since it has custom serializer GWT dosn't know which custom class have been put inside RpcMap, and it doesn't generate serializers for them. So when you put some field into your BaseModel class, gwt knows that it might need to be able to serialize this class, so it will generate all the required stuff for this class.
Porting GXT2 Application code using BaseModel to GXT3 Model is uphill task. It would be more or less completely rewrite on model side with ModelProviders from GXT3 providing some flexibility. Any code that relies on Model's events, store, record etc are in for a rewrite.