JSF 1.2: Too many small session beans: Is it bad and what the alternatives - performance

There's a JSF 1.2 application with no way to switch to another version/technology in the observable future. It's often needed to show a small (modal) form that needs some state kept across several requests. After the work is done (confirmed or canceled) this state is not needed until the form opens again. There are a lot of such forms and session objects (separate per-form session beans or members of special huge session beans) are used for keeping their state. The sessions may last long enough, probably the whole working day. So a lot of objects unnecessarily load the session scope.
Is there a simple, standard way of cleaning a session object when it's no longer needed? What are your solutions regarding to that?

# Alex,
As you have mentioned that you have multiple view/page that you want to render/preserve in multiple requests and that remain persist until user session is not expire .
This is only because bean scope is session , May be you have did it is to avoid multiple db call to achieve performance just avoid reloading same info from database on each request.
I think you create a collection in user session bean or any other session bean where you find best (as per your choice but I will advise to create New Bean for only this purpose).
In this collection you just put your model data what you want to display on page do not register this bean in context file. persist the object where you required like you have three pages .P1,P2 & P3 and after P3 you want to remove model1 (your pojo)from session then on navigation event just remove model1 from collection .
//Sample code which help to understand what I am saying
#Session
UserBean {
Map tempBean<Obejct,String>=new HashMap<Object,String>();
//just for example suppose you want to load Model1
public Model1 viewP1() {
if(tempBean.get("P1info")==null){//key for P1 view
Model1 m1=db.getP1info();
tempBean.put("P1info",m1);
}
return (m1)tempBean.get("P1info");
}
}
To remove the Model1 data from session just set the value as null for key "P1info" in case of above code, You can use WeakHashMap,If you do not want to remove key from Map.But make sure to delete value part on your trigger of event after which you do not want to persist the Model1 value in session.
I hope this will work in your case .Please let me know in case of any problem in implementation since I have not shared working code ,but only showing concept.

Try to give a look here
link
I would run a remove on all the object once "the work is done".

Related

Problems with Spring Forms and Validation

I am newer to Spring, previously I've worked in PHP and Python. I am having some issues understanding how Spring forms work and are validated. My understanding thus far is that when you are using the your form is backed by a bean, meaning you must provide a bean to the JSP. You can also use the stand HTML forms but then you have to manually retrieve the request parameters in the controller.
Here is the issue I am having. I have a User bean that is using Hibernate Validator, and I have add, edit pages for users. The issue is I don't want the password field to appear on the Edit page, the password is going to be garbage anyway because its using BCrypt. However when the form is submitted validation fails because it expects the password to be present. There doesn't seem to be anyway to do partial bean implementation using Spring Form.
I would like to use Spring Form if possible because it reduces repetitive validation code, and its always nice to work with objects. My thoughts now are do I create an intermediate object and then translate the data from that to my bean. Seems tedious and can lead to the creation of way to many objects. My other thought is to just using plain old HTML forms and pull the params myself and set the values in the object.
I'm not sure what is the best approach or if I'm even thinking on the right track. Spring Forms and the validation is offers seems great, but seems like it isn't particularly flexible. Like I said I'm new to Spring so I may just be missing something or not understanding.
Another issue I have been wrestling with is having multiple objects needed on a form. Lets say I have a User bean, which has the following Properties.
private Role role;
private Country country;
So I need to pass User, List, and List to my JSP. I can get them to display fine, however if the form validation fails when it returns to that page, I lose my role and country objects, unless I re-add them to the model before returning the view name. Am I missing something here or is that the norm. It's a request object so I guess that makes sense but seems tedious to have to re-add them every time.
My understanding thus far is that when you are using the your form is
backed by a bean, meaning you must provide a bean to the JSP.
I'd say mostly true. The form is backed by a bean, but the Spring JSTL tags know how to get to the bean based on the set modelAttribute. The bean is living in what you would consider "page" scope, unless you add set your model attribute to be in session. Either way, if you are using the Spring JSTL tags, they are going to one or the other place to get it.
You can also use the stand HTML forms but then you have to manually
retrieve the request parameters in the controller.
Not true. You can "simulate" the same thing that the Spring JSTL tags are doing. Understand that JSTL tags are very much like macros. They are simply copying in some pre-determined block of code into the output with some very rudimentary conditional statements. The key bit that Spring MVC needs to wire the Model Attribute on the Controller side is the name and value, which are easy to decipher how those get generated/wired together.
However when the form is submitted validation fails because it expects
the password to be present.
You could create a "DTO" or "Data Transmission Object", which is basically a go-between to take the values from the UI and are converted in the Controller/Service layer to the real Model objects on the backend. Or, if you are lazy like me, put the User in session scope, in which case you don't have to post the value as Spring will take the one out of session and just updated the one or two fields you did post. Don't post the password, Spring wont set the password.
My thoughts now are do I create an intermediate object and then
translate the data from that to my bean.
Yes, this is the DTO I referred to. You only need to do it where you need to.
I'm not sure what is the best approach or if I'm even thinking on the
right track.
There are probably thousands of ways to do anything in coding, some more right or wrong than others. I know some developers who are design-Nazi's and would say you should always do it one way or another, but I am not one of those people. I think as long as you are consistent, and you are not doing something completely boneheaded you are on the right track. My #1 concern with all the code I write is maintainability. I
Don't want to spend 20hrs trying to re-learn what I did 6mo ago, so I tend to choose the simpler option
Hate repeating code, so I tend to choose more module designs
Hate having to spend 20hrs trying to re-learn what I did 6mo ago, so tend to make heavy use of JavaDoc and comments where I find the code is tricky (lots of loops, doing something weird, etc)
Another issue I have been wrestling with is having multiple objects
needed on a form.
There are several ways to deal with this too. I have never used it, but you CAN actually have more than one Model Attribute associated with the same form and Controller handler. I think you use a <spring:bind> tag or something. I have seen samples around, so Google it if you think you need that.
My approach is usually to either put something in session or build a DTO to hold all the things I need. The first I use more for things like lists to drive building the view, for instance if I have a drop down of States coming from a table. I would have a List of the States put into session and just use them from there, that way I only go after them once and done.
I use the DTO approach (some might call it a Form Bean) when I have a complex gaggle of things I need to change all at once, but the things are not necessarily connected directly. Just to point out: You can have nested objects in your model attributes and use them in your Spring JSTL tags. You can also have Collections (List, Set, Map) in your Model Attribute and get to those as well, although Spring doesn't handle nested Collections very well.
Hope that helps.

Entity Framework in detached mode with MVC application

I have started working out with Entity Framework (EF) for an MVC n-tier application. It would seem that very obvious that this being a web application (which is stateless), I would have to use detached object models. There is no ambiguity with doing an Add operation. However when doing an edit there are here are two ways
Fetch the original object in context, attach the updated object and
then save to database. Something like mentioned in answer to this
question
EF4 Context.ApplyCurrentValues does not update current values
Set individual modified properties explicitly using the IsModified property of individual fields of the object like
mentioned in this article
http://msdn.microsoft.com/en-us/data/jj592677.aspx
Method 1 has disadvantage of having to load object into memory from database each time an update needs to be performed.
Method 2 would require having to manually pass which fields to be set as IsModified to true from wherever the object an be updated. So for e.g. for each object, I may need to create a boolean collection object for each field of the object.
e.g.
SaveEntity(EntityClass e, EntityStateClass ec)
{
context.Entry(e).Property("Name").IsModified = ec.NameState;
context.SaveChanges();
}
class EntityStateClass{ public bool NameState;}
I would prefer method 2 simply for the sake of performance but I am hindered by the n-tier architecture and repository pattern I am using. My Repository interface restricts save method for any object to be
SaveEntity(EntityClass e);
So I cannot pass the "state" object. Context class is not available and should not be available outside DAL. So I cannot set property outside. Is there any "proper" way to achieve this ?
Note: Self-Tracking Entity is also out of question since I cannot send entities with state to client (the browser) since I am intent on keeping the html lightweight.
EDIT: After a lot of thinking, I am trying to use following mechanism to keep track of modified state for each field in my domain class
Declare a partial class for entity class.
For each field that is updateable, declare a boolean property like "IsModified_FieldName"
Set the "IsModified_FieldName" property when the field is set.
However for this I need Entity Framework to generate explicit properties for me instead of implicit properties that it auto-generates. Does EF provide an handle to do this ?
Here is sample code of what I am trying to achieve
//Save Method for class EntityClass.
SaveEntity(EntityClass e)
{
context.Entry(e).Property("Name").IsModified = e.IsModified_Name;
context.SaveChanges();
}
//EntityClass is class autogenerated by EF
public partial class EntityClass
{
//This is auto-generated property by EF
public string Name {get; set;}
/* This is what I would like EF to do
private string name;
public string Name
{
get {return Name;}
set {
name = value;
//this is what I would like to do
this.IsModified_Name = true;
};
}
*/
}
//This is another partial definition for EntityClass that I will provide
public partial class EntityClass
{
//This property will be set to true if "Name" is set
public bool IsModified_Name {get; set;}
}
PS: It seems the information I have provided is not sufficient and therefore there are no responses.
I am using DbContext (Database first model)
EF auto-generates the class files for me. So each time I update my database, the class files are regenerated.
To your concrete question: The entities are generated by a T4 template and it should be possible to modify this template (which is in text format) to generate the entities in a way you want to shape them.
But I have a few remarks about your concept:
In a web application data are usually changed by a user in a browser. To have a definite knowledge what really has been changed you need to track the changes in the browser (probably by some Javascript that sets flags in the data (a ViewModel for example) when a user edits a text box for instance).
If you don't track the changes in the browser what happens? The data get posted back to the server and you don't know at the server side (with MVC in a controller) which property has been changed. So, your only chance is to map all properties that has been posted back to your EntityClass and every property will be marked as Modified, no matter if the user really did a change or not. When you later call SaveChanges EF will write an UPDATE statement that involves all those properties and you have an unnecessary overhead that you you want to avoid.
So, what did you win by setting individual properties instead of setting the whole entity's state to Modified? In both cases you have marked all properties as Modified. Exceptions are partial changes of an entity, for example: You have a Customer entity that has a Name and City property and a view that only allows to edit the Name but not the City and a corresponding ViewModel that only contains a Name property. In this case your procedure would only mark the Name property of the Customer entity as Modified but not the City. You might save here a little bit because you don't save the City property value to the database. But you still save the Name even if it didn't change.
If you use solution 1 (ApplyCurrentValues) you have to load the entity first from the database, yes, but it would only mark the properties as Modified that really changed compared to their values in the database. If the user didn't change anything no UPDATE would be written at all.
Keep in mind that you are only at the beginning to implement your concept. There are other changes to the data that can happen in the browser than only scalar property changes, namely relationship changes. For example a user changes the relationship from an Order to a Customer or you have a view that has an Order and a collection of OrderItems and the user cannot only edit the Order header but also edit the OrderItems and remove and add new OrderItems. How do you want to recognize when the data come back from the browser to the server which collection item has been added and which has been removed - unless you track all those changes in the browser and send tracking information back to the server in addition to the actual data or unless you reload the Order and OrderItems from the database and merge the changes into the original entities from the database?
Personally I would vote for option 1 for these reasons:
You can use real POCOs that don't carry additional tracking information. (BTW: I have some doubt if you aren't reinventing the wheel by implementing your own tracking that EF change tracking proxies provide out of the box.)
You don't need to track changes in the browser which can become quite complex and will require Javascript in every Edit view to write change flags into hidden form fields or something.
You can use standard features of EF without having to implement your own tracking.
You are required to load entities from the database when you want to update an entity, that's true. But is this the real performance bottleneck in a web application where data have to run through the wire back and forth (and reflection (which isn't really known as to be fast) is involved by the model binder)? I have nothing said if your database is remote from the web server and connected by a 9600 baud modem. But otherwise, your plan is not only premature optimization, it is kind of premature architecture. You are starting to build a potentially complex architecture based on "it could be slow" to solve a performance problem that you actually don't know of whether it really exists.

DBContext, state and original values

I'm working with ASP.NET MVC3 using EF and Code First.
I'm writing a simple issue tracker for practice. In my Controller I have a fairly standard bit of code:
[HttpPost]
public ActionResult Edit(Issue issue) {
if (ModelState.IsValid) {
dbContext.Entry(issue).State = EntityState.Modified
.....
}
}
Question part 1
I'm trying to get my head around how the dbcontext works -
Before I've set the State on the dbContext.Entry(issue), I assume my issue object is detached. Once I set the state to be modified, the object is attached - but to what? the dbContext or the database? I'm kind of missing what this (attaching) actually means?
Question part 2
For argument's sake, let's say I decide to set the "Accepted" field on my issue. Accepted is a boolean. I start with it being false, I'm setting it to true in the form and submitting. At the point that my object is attached, what is the point of the OriginalValues collection? for example if I set a breakpoint just after setting EntityState.Modified but before I call SaveChanges() I can query
db.Entry(issue).OriginalValues["Accepted"]
and this will give me the same value as simply querying the issue object that has been passed in to the Edit....i.e. it is giving the same result as
issue.Accepted
I'm clearly missing something because the documentation says
"The original values are usually the entity's property values as they were when last queried from the database."
But this is not the case because the database is still reporting Accepted as being false (yeah, I noted the word "usually" in the docs but my code is all pretty much standard generated by MS code so....).
So, what am I missing? what is actually going on here?
The context can work only with attached entities. The attaching means that context know about the entity, it can persists its data and in some cases it can provide advanced features like change tracking or lazy loading.
By default all entities loaded from the database by the context instance are attached to that instance. In case of web applications and other disconnected scenarios you have a new context instance for every processed HTTP request (if you don't you are doing a big mistake). Also your entity created by model binder in HTTP POST is not loaded by that context - it is detached. If you want to persist that entity you must attach it and inform context about changes you did. Setting state to Entry to Modified will do both operations - it will attach entity to the context and set its global state to Modified which means that all scalar and complex properties will be updated when you call SaveChanges.
So by setting state to Modified you have attached the entity to the context but until you call SaveChanges it will not affect your database.
OriginalValues are mostly useful in fully attached scenarios where you load entity from the database and make changes to that attached entity. In such case OriginalValues show property values loaded from database and CurrentValues show actual values set by your application. In your scenario context doesn't know original values. It thinks that original values are those used when you attached the entity.

Updating a many-to-many relationship

I've asked the question a few different times in a few different ways and I haven't yet gotten any responses. I'm trying again because I feel like my solution is too convoluted and I must be missing something simpler to do.
Using EF 4.1, POCO, DbContext API, AutoMapper, and Razor in an MVC 3 application.
I have a many-to-many relationship between two of my entities: Proposals and CategoryTags. I can successfully map (Automapper) a Proposal to my ProposalViewModel including the collection of CategoryTags.
In my View, I use javascript to allow the user to add, update, and remove tags by dynamically creating elements, each one that stores the ID of the chosen tag.
I can successfully post my ViewModel back to my controller with it's CategoryTags collection populated (although only with the ID property for each CategoryTag).
When that ViewModel is posted back to my controller, I don't know how to get those tags from the ViewModel and add them to my Model in such a way that db.SaveChanges() updates the database properly.
The only way I've had any success is to disconnect the CategoryTags collection in mapping (by namig them differently), iterate through each tag and manually look it up in my context and then call the .add() method. This is sloppy for a number of reasons which leads me to believe I'm doing it wrong.
Can anyone offer any direction at all?
UPDATE:
For anyone who is interested, my functional code:
Dim p As New Proposal
Dim tempTag As CategoryTag
p = AutoMapper.Mapper.Map(Of ProposalViewModel, Proposal)(pvm)
db.Proposals.Attach(p)
db.Entry(p).Collection("CategoryTags").Load()
For Each ct In pvm.Tags
tempTag = db.CategoryTags.Find(ct.Id)
If tempTag Is Nothing Then
Continue For
End If
If ct.Tag = "removeMe" Then
p.CategoryTags.Remove(tempTag)
Continue For
End If
p.CategoryTags.Add(tempTag)
Next
db.Entry(p).State = EntityState.Modified
db.SaveChanges()
Return RedirectToAction("Index")
The only working way is doing this manually - you can read full description of the problem if you want. The description is related to ObjectContext API but DbContext API is just wrapper suffering same issues (actually DbContext API suffers even more issues in this scenario and because of that I will skip solution with manually setting relationships).
In short. Once you post your data back to the controller you must create new context instance and attach your Proposal and realated CategoryTags. But after that you must inform the context about changes you did. It means you must say context which tags have been added to proposal and which have been removed. Otherwise context cannot process your changes because it doesn't do any automatic merge with data in database.
The easiest way to solve this is loading current Proposal with related CategoryTags from database (= you will have attached instances) and merge incoming data into attached object graph. It means you will manually remove and add tags based on posted values.

Attaching an object to another context in EF 4

I have a baseclass in my website with a property: CurrentUser.
The get method of this property will create a new context and get a User object from the database based on auth cookie information. So far so good.
But since the context is closed, all I can do outside this, is to call properties directly under User, for example FirstName.
But as soon as I try to get a relation for example, like CurrentUser.UserOffices this won't work since I didn't include UserOffices in the query.
Is there a way to create a new context outside the baseclass which I can attach the CurrentUser object to? I have tried ctx.Attach(CurrentUser) with no luck.
You may wonder why I don't include UserOffices. This is simply because there are very many relations to different tables and I don't want to include them all since it differs between my web pages what relations are needed.
Any ideas?
You can try to Attach your entity and then explicitly load property:
ctx.Attach(CurrentUser);
ctx.LoadProperty(CurrentUser, u => u.UserOffices);
I'm not sure if this works with POCOs.
You can also query for object again with Includes specifing navigation properties you need.
The other choice is simply load UserOffices with Linq-to-entities query restricting where condition to current user.

Resources