I might be an idiot here but I have a question regarding xpages and managed beans. I'm trying to separate logic and presentation by moving logic to a bean corresponding to an entity (a document more or less). I have a data-provider-class fetching and setting data. This is fine and all with one xpage but as the application gets more advanced with relations and multiple xpages I run into a problem (I'm looking at http://blog.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm?opendocument&comments#anc1 for inspiration).
If I'm not wrong I can't assign different managed beans to different xpages so setting different data-provider-classes and businesslogic-beans to different xpages can not be done in faces-config.xml. Now I might be going about this in the wrong way but any pointers is most appreciated.
Best regard
Olof
You cant assign managed beans (as in define them in faces-config) for specific xpages ( as far is i know). They are application specific. I think you are looking for something like the factory pattern/creator pattern. These are design patterns used to create instances of a specific class. For more info see: Factory method pattern Wikipedia or Creational patterns wikipedia.
When you create for instance a pizzeria website you could have a factory to create specific types of pizza's depending the button you are pressing. Each pizza is then created in memory ( bean ) and used as the datasource of your custom control. When the customer is ready ordering the pizza is saved to a notesdocument ( saved state ) and transformed together with all other products orderd as an order for that customer.
Whenever you want to retrieve that particular pizza again (for instance when you want to check which pizza the customer has ordered) you only need to ask the factory if you can get pizza with number / ID and the factory will return that pizza from the notesdocument. Build once, use many.
So basically you don't have several managed beans per page but per application and you use them across your application wherever you need them.
Look at beans as "global variables", so you can have different functions by defining different names. For example: "invoice", "customer", "order", "orderItem" and so on. It's up to you.
Related
We're refactoring our solution to a Domain Driven Design structure. Our consultants which implement the software, should be able to customize some behavior of the application (for specific customers needs). For example they want to add custom defined properties to the presentation (user input forms) and save the custom data together with the entities defined in our DDD projects.
However, the domain objects should preferably not contain a customData property. I don't want to mix those and let the domain object know that there's something like custom data. I'm saving en fetching the entities by Repositories.
How do I make this scenario possible? One possible solution would be:
Query the entity by using his Repository
And query separately the CustomPropertiesRepository by entity ID.
Combine the two queries objects.
When saving the forms. It will be splitted again using two repositories
The disadvantage of this, is that I have to query twice though it should be one document.
Any advice on this problem?
in general dynamic properties are better suited for data-centric design and in my opinion this practice is not suitable for DDD.
in DDD the code must reflect the knowledge of the domain, it must be simple and explicit.
before thinking of the best way to persist a dynamic property, you must solve the problem at the design level:
1-There are three possible artifacts for a property: aggregate root, entity or object value.
2-usually a dynamic property brings with it a functional need (calculation, validation ... etc), where you will implement this functionality? whether in the aggregate root or in a domain service you will be compelled to compile your code and here the dynamic propriety loses its meaning, unless you think use a Business rules engine, and there you introduce another new paradigm with its whole complication, and some of your business logic would be outside aggregates and domain services.
In my system, I have some entities that conceptually inherit from User. For instance, I can have suppliers and regular consumers. I wish to extend the User entity, so that I can inherit all of user benefits like register, login, lost password and so forth.
I though about a few options:
1. Extending the User entity using one of the Hibernate inheritance strategies (https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/inheritance.html), but it looks like a lot of changes in the code is needed. I'd also have to make sure the tables generation would be also correct and working fine with liquibase;
2. Adding all necessary attributes to the User entity and then adding suppliers and consumers as roles. I just don't feel comfortable by doing this since the User table wouldn't be normalized;
3. Creating a relationship from each of these entities to the User entity, but in this case, I don't clearly see how to inherit the user management benefits.
Has anyone ever done something similar so that could shed some light on this?
Thanks in advance.
I would rather use composition over inheritance. So basically, you would have Supplier holding a one-to-one relationship with User. This way, you let JHipster User related code unchanged.
User management feature has not yet been released so let's focus on user registration then how would a user qualify as a supplier or customer? Are they supposed to choose by themselves? Can a user be both a consumer and a supplier?
For me the simple JHipster CRUD screens will not be enough, you must be prepared for building your own screens for better UX. So, I would rather focus on having a strong data model and REST API.
I found a way following the second approach.
I added all the attributes for each subclass (in my example, Suppliers and Customers) to the table User (JHI_USER) and a type attribute as well so that I can know which type of user I'm handling. I added also their respective attributes to the User class and updating the related classes, like UserService, UserRepository, test classes and so forth. I used the concept of roles too, but just to provide permissions to each section of the site.
After that, I created an AngularJS state for each user type, passing its type (kinda like a discriminator). For instance, I created a state called /registerSupply passing its type = 'S'. I then edited the original register page to add all the additional suppliers and customer attributes, filtering them out based on the user type and that is it.
As I stated, I don't feel comfortable by using this approach, but in the end, it's basically one of the strategies suggested by Hibernate (https://docs.jboss.org/ejb3/app-server/tutorial/singleinheritance/single.html), which makes me feel a bit better.
The preferred way explained in this issue is to use Git. Just add your code manually, and use git merge when you regenerate your code from JDL.
Using composition would create a JOIN that has performance impact on a massively used entity. Entity inheritance works but is hard with JPA and would even harder with generated code.
If I had to choose between composition and inheritance, I would prefer here composition with caching when the application grows.
I'm trying to implement a proper layer separation in my XPage project. Ideally I'm trying to get to a point where the XML in the XPage contains no SSJS and uses only EL to access Java objects.
So far I've worked out how to load all my data from the domino database into Java Beans (where 1 document = 1 Object, more or less), I'm reading view contents into Java Maps or Lists, and I've managed to display the content of these collections in repeat controls.
What I'm unsure of is how to display the content of a 'form', of a single document, without referencing the domino document. In particular, I'm unsure of how to deal with the 'new document' case. I suppose I create an empty object, then set that object as a data source for the Xpage.
I'm aware that I have to use a ObjectDataSource for this, but I'm unsure where to actually store it. I read an article from Stephan Wissel stating that one shouldn't put them in managed bean, so where can I put it? In one of the scoped variables like viewScope?
Right now I've written an 'ApplicationBean' which is a session-scope Managed Bean where I'm storing all my objects.
What is the best practise? It seems that there are many different ways to meet that goal. Currently I'm exploring Christian Güdemann's XPages Toolkit, which sounds very promising. I know that Samir Pipalia, John Daalsgard and Frank van der Linden have worked up their own frameworks.
So how should I go about it? Any pitfalls?
This is a large topic indeed. As Paul mentioned, Tim's document model classes are a great example of how to do that clearly, and Tim goes into more detail in later episodes in that NotesIn9 series. My own Framework's model objects are fairly similar, though I also added collection managers to handle the dirty business of accessing views. For better or for worse, almost every XPage developer solves this problem in a unique way.
There are a number of ways you can go about implementing this sort of thing, and some of the differences aren't terribly important in normal cases (for example, whether you preload all data from the document when constructing the model object or do lazy fetching to the back-end only as needed), but there are definitely a couple overarching questions to tackle.
Model Access
As you mentioned in the question, one of the big problems is how you actually access model objects from the XPage - how the objects are fetched from the DB or created anew. My Framework's model objects use a conceit of "Manager" objects, which are application-scoped beans that allow getting either named collections (which map to views), model objects by UNID, or a new model object via the keyword "new". Generally, these models (which are Serializable) are then stored in the view scope of the page using them either via <xp:dataContext/>, <xe:objectData/>, or the Framework's own <ff:modelObjectData/>.
I've found it very wise to avoid using managed beans to represent individual objects (like "CurrentWhatever" that you then fill with data on each page), since that muddies up your faces-config in the best case or runs into session problems in the worst (if you put it in session scope, which I rarely use).
How you implement "new" vs. "fetched" model objects depends largely on the tack you take to write your models in the first place, but most boil down to having two constructors: one to take a UNID (at least) to point to existing document and one to create a new one. If you go the "write every properly explicitly in the object with getters and setters" route, the latter would also initialize all of the fields with default values instead of reading them from a document. Internally, you should have fields to store the UNID of the document, which can indicate whether it's new or not - then, your save method can check if this field is empty and create a new document if needed (and then store the new doc's UNID in the field).
Views
It sounds like you're already reading your model collections into Lists, which is good. One down side there, though, is scalability: with small (less than 100) collections, you're likely to not run into any load-speed problems, but afterwards things are going to slow down on initial page load as your code reads in the entire view ahead of time. You can mitigate this somewhat with efficient view reading, but there's a limit. The built-in views are generally speedy because they only load data as needed (they also cheat like hell to do so, but that's another issue).
This is a noble goal to aim for yourself, but doing so to cover all cases is no small feat: you end up running into questions of FT searching, column resorting, efficient data preloading (you don't want to re-open the View object only to read in one entry at a time, but you also don't want to read the whole thing), use in viewPanel and maybe others (which require specialized interfaces), expanding/collapsing categories, and so forth. It's a large sub-topic on its own.
Esoterica
You're also liable to run across other areas that are more difficult than you'd think at first, such as "proper" rich text handing and file attachments. Attachments, in particular, require direct conflict with the XSP framework to get to function properly with custom model objects and the standard upload/download controls.
Case-sensitivity in field names is another potential area of trouble. If you're writing getters and setters for all of your fields, it's a moot point, but if you're going the "thin wrapper" route (which I prefer), it's important to code any intermediary caches/lookups in a way that deal with the fact that "FOO" and "foo" are (basically) the same as item names to Notes, but are distinct in Java. The tack I take is to make extensive use of TreeMaps: if you pass String.CASE_INSENSITIVE_ORDER as the parameter to the constructor, it handles treating Strings as generally case-insensitive when used as keys.
Having your model objects work with all the standard controls like that may or may not be a priority - I find it very valuable, so I did a lot of legwork to make it happen with my framework, but if you're just going to do some basic Strings-and-numbers models, you don't necessarily need to worry.
So... yeah, it's a big topic! Depending on how confident you are with Java and the XPages undergirdings, I would suggest either going the route of fairly-simple "beans with getters and setters" for your objects or by looking into the implementation details of one of the existing frameworks (my own or the ones you mentioned). Sadly, there are a lot of little things that will crop up as your code gets more complicated, many of which are non-obvious to deal with.
Jesse Gallagher's Scaffolding framework also accesses Java objects rather than dominoDocument datasources. I've used (and modified) Tim Tripcony's Java objects in his "Using Java in XPages series" from NotesIn9 (the first is episode 132. The source code for what he does is on BitBucket. This basically converts the dominoDocument to a Map. It doesn't cover MIME (Rich Text) or attachments. If it's useful, I can share the amendments I made (e.g. making field names all the same case, to ensure it still works for existing documents, where fields may have been created with LotusScript).
Andrew - Jesse's one of the experts here so I'd read his response carefully.
What I do is I took one of the key pieces of Jesses bigger framework - the "pageControllers" and I use that HEAVILY. So I end up with a Java Class for each XPages to act as the controller. "All" Jesse's page controller framework does is make it a little easier to consume. So you can reference it on each page as "controller" and don't nee dot make individual managed beans for them.
I still will use SOMES SSJS on the XPage if I really need to for things like button events.. some methods that don't have proper getters and setters.. HashMap.size() for instance. But the vast bulk of the code goes into the Java Class. No real need for viewScope variables any more as well.
in the case of a "New Document".. In the controller I'll create a new Java Object that represents the "Current document". I'll bind all the fields to that. If it's new I create a new Object and assign it to the private variable. If I'm loading form somewhere then I take that variable and load the document I want.
I've started to really try and detail this in more recent NotesIn9's. Especially the little series on Java for Xpages developers. I think I got far enough there to show you what you need to know. I do plan on doing a lot more on this topic as soon as I can.
I´m a little confused about inheritance and relationships in core data, and I was hopping someone could drive to the right path. In my app i have created 3 entities, and none of them have (and are not suppose to have) common properties, but there´s gonna be a save and a load button for all the work that the user does. From my understanding I need to "wrap" all the entities "work" into an object which will be used to save and load, and my question is, do I need to create relationships between the entities? Because I have to relate them somehow and this is what make sense to me. Is my logic correct?
I'm implementing a budget calculator, and for the purpose of everyone understand what my issue is, I´m going to give an practical example and please correct me if my logic is incorrect:
Let´s just say you are a fruit seller, and because of that it´s normal to have a database of clients and also a fruit database with the kinds of fruit you sell. From my understanding I find two entities here:
Client with properties named: name, address, phone, email, etc.
Stock with properties named: name, weight, stock, cost, supplier, etc.
TheBudget with properties named: name, amount, type, cost, delivery, etc.
I didn´t put all the properties because I think you get the point. I mean as you can see, there´s only two properties I could inherit; the rest is different. So, if I was doing a budget for a client, I can have as many clients I want and also the amount of stock, but what about the actual budget?
I´m sorry if my explanation was not very clear, but if it was..what kind of relationships should I be creating? I think Client and TheBudget have a connection. What do you advise me?
That's not entirely correct, but some parts are on the right track. I've broken your question down into three parts: relationships, inheritance and the Managed Object Context to hopefully help you understand each part separately:
Relationships
Relationships are usually used to indicate that one entity can 'belong' to another (i.e. an employee can belong to a company). You can setup multiple one-to-many relationships (i.e. an employee belongs to a company and a boss) and you can setup the inverse relationships (which is better described with the word 'owns' or 'has', such as 'one company has many employees).
There are many even more complicated relationships depending on your needs and a whole set of delete rules that you can tell the system to follow when an entity in a relationship is deleted. When first starting out I found it easiest to stick with one-to-one and one-to-many relationships like I've described above.
Inheritance
Inheritance is best described as a sort of base template that is used for other, more specific entities. You are correct in stating that you could use inheritance as a sort of protocol to define some basic attributes that are common across a number of entities. A good example of this would be having a base class 'Employee' with attributes 'name', 'address' and 'start date'. You could then create other entities that inherit from this Employee entity, such as 'Marketing Rep', 'HR', 'Sales Rep', etc. which all have the common attributes 'name', 'address' and 'start date' without creating those attributes on each individual entity. Then, if you wanted to update your model and add, delete or modify a common attribute, you could do so on the parent entity and all of its children will inherit those changes automatically.
Managed Object Context (i.e. saving)
Now, onto the other part of your question/statement: wrapping all of your entities into an object which will be used to save and load. You do not need to create this object, core data uses the NSManagedObjectContext (MOC for short) specifically for this purpose. The MOC is tasked with keeping track of objects you create, delete and modify. In order to save your changes, you simply call the save: method on your MOC.
If you post your entities and what they do, I might be able to help make suggestions on ways to set it up in core data. You want to do your best to setup as robust a core data model as you can during the initial development process. The OS needs to be able to 'upgrade' the backing store to incorporate any changes you've made between your core data model revisions. If you do a poor job of setting up your core data model initially and release your code that way, it can be very difficult to try and make a complicated model update when the app is in the wild (as you've probably guessed, this is advice born out of painful experience :)
Please share your view on this kind of thing i'm currently testing out :
Have an JPA entity inside my JSF managed bean
Bind the entity's properties to the JSF form elements like input text, combo, even datatable for the entity's list of detail objects for example.
Have the entity processed by a service object, meaning the entity object itself, and perhaps with some other simple variables / objects
The service will do some basic validation or simple processes, and deliver the entity object to the DAO layer to be persisted
And the JSF view will reflect on the detached entity
Is this kind of solution with passing the entities between tiers OK ?
Forgive me for my inexperience in this matter, since i was used to play with 'variables' in webapp (using map based formbean in struts 1), but i've read about transforming the entity objects into some other format, but i'm not sure what it is for ?
If the relations between entities are defined, we can bind it to JSF components, and therefore render based on and populate the entity's properties.
Yes, this is perfectly fine and in fact the recommended way to do it nowadays.
This "transforming the entity objects into some other format" refers probably to the Data Transfer Object pattern, which was necessary in the bad old days before annotations, when entity classes usually had to inherit from some framework-specific base class, undergo bytecode manipulation or were implemented as proxy objects by an EJB container.
Such entity objects were either impossible to serialize or contained much more state than the actual entity data and therefore would waste a lot of space when serialized. So if you wanted to have a separate app server tier, you had to use the DTO pattern to have it communicate efficiently with the web tier.