How to store textarea input into a database with hibernate? - java

I made a textarea in a jsp file called information.jsp and im trying to get it to store the input from it into a database when the user clicks submit. I've made the information.hbm.xml file as shown below:
information.jsp:
<textarea id = "desc" rows="5" cols="115" onkeypress="textCounter(this,20);"><c:out value="${informationView.storedDescription}"/></textarea>
information.hbm.xml
<hibernate-mapping>
<class name="Information" table="INFO_USER">
<id name="id" type="long" column="INFO_ID">
<generator class="native">
<param name="sequence">ID_SEQ</param>
</generator>
</id>
<property name="description" column="DESC"/>
</class>
</hibernate-mapping>
I then made a class Information with getters and setters for description to store and retrieve the information from the database. I just cant figure out how to get the input into description from the textarea from a submit event...
From what I've been reading I think I have to make an InformationAction to actually get it to save when someone clicks submit but again not sure. I'm new to Hibernate and a little lost on where I went wrong in the process of saving the input to the database and retrieving it to load into the textarea automatically if someone reopens the page.
I just can't figure out how I'm going to pass the input from the textarea to the database.
Any help would be great since I've been working on this for a long time and can't figure it out. Let me know if you need more info, thanks.

Yes you will need either InformationAction or InformationContoller depending on the web framework you want to use. Your action or controller needs to have a description property that maps to the text area value. If you use web frameworks like Struts2 or Spring MVC, this is pretty easy to achieve.
Now coming to hibernate part. Your action needs to have hibernate Session object that can read and write values to the database. You can then construct your Information object using the description you got from front end and then call saveOrUpdate() method on session.
The code would be something like this
public class InformationAction {
//Maps to text area value. Needs getter and setter
private String description;
//Inject session from hibernate configuration
private Session session;
public void someMethod() {
Information information = new Information();
information.setDescription(description);
session.saveOrUpdate(information);
}
}
This will save a row in your Information table.

Related

Best way to edit an object with Thymeleaf and Spring MVC

I'm working on a website in which users can add and edit things (it's not relevant describing what these things are in particular).
I'm implementing it using Thymeleaf for the frontend, Spring MVC for the backend and JPA for the database logic. Now I'm trying to implement the edit logic but I don't know which is the best way to do it.
What I'm thinking is: display to the user all the input fields (on a HTML page) that he is allowed to edit, already filled in with the current values. He can edit then whatever fields he wants and finally press the edit button to persist the changes.
Once I get the new object in the backend, I retrieve the old version from the database in order to check which field the user changed. For every field that got changed I update the old version and only when I've finished I call the JPA method save and I persist the new version of that object.
Is there a better way to do it?
It would be perfect if the object I put inside the model in order to display all its field to the user inside the HTML page, could mantain all the information of the old object and not just the ones the user can change. Let me explain better what I'm trying to say with an example:
Let's say the object we are trying to edit its called Person and has these attributes:
id
name
surname
money
nickname
sex
But the user can edit only the following attributes:
money
nickname
sex
so the controller which handler the get request of the page would look like this:
#GetMapping("person/{personId}/edit")
public String getEditPersonPage(#PathVariable Integer personId, Model model) {
Person person = personService.getById(personId); //person has all the attributes filled in
model.addAttribute("person", person);
and the controller which handler the put request looks like this:
#PutMapping("person/{personId}/edit")
public String editPerson(#ModelAttribute Person person, #PathVariable Integer personId){
personService.editPerson(person); //person has only the three fields filled in and all the other attributes as NULL
return "redirect:/person/" + personId;
}
the HTML page:
<form th:object="${person}" th:method="PUT">
<fieldset>
<p th:text="*{id}"></p>
<p th:text="*{name}"></p>
<p th:text="*{surname}"></p>
<input type="number" th:field="*{money}" th:value="*{money}" />
<input type="text" th:field="*{nickname}" th:value="*{nickname}" />
<input type="text" th:field="*{sex}" th:value="*{sex}" />
<input type="submit" value="Edit" />
</fieldset>
</form>
When I insert the object person inside the model to render the HTML page the object has all the attributes. Indeed I can decide which of its attributes display inside the HTML page (in this case only three: money, nickname and sex). But when the user press the submit button (edit), I receive only the fields displayed inside the HTML page (money, nickname, sex). So what I have to do is: I have to take these three fields, check if they are changed and if so, update the old version.
It would be perfect if when the user press the submit button, all the fields of person (and not just those three he is allowed to update) could be retrieved by the controller. In that case I could skip the check phase and persist directly the new version inside the database (with the old values unchanged and not set to NULL).
Any thoughts?
You can use readonly attributes for the ones that are not going to be edited.
I think is the best way in order to keep all the values visible in the form to give all the info to the user that is editing. All the values will be submitted and serialized with your object, but the form just allows to edit the three of them that you need.
A readonly element is just not editable, but gets sent when the according form submits. A disabled element isn't editable and isn't sent on submit.

How to know if lazy loading worked via hibernate mapping?

I have a Person object with 5 columns and i used following properties:
property name="firstName" column="FirstName" type="string" lazy="false"
property name="lastName" column="LastName" type="string" lazy="true"
property name="city" column="City" type="string" lazy="true"
property name="country" column="Country" type="string" lazy="true"
property name="phone" column="Phone" type="string" lazy="true"
Now how do i find out if the object i get back using "From Person" contains only rows of data with the FIRSTNAME within it - assuming the other 4 are lazy loaded. I tried debugger but when i dive in i see all values has already been there... is there something missing? thanks
This might be helpful :When asked to load a lazy field, Hibernate loads all lazy fields
But, I thing it will not improve performance significantly, if it is a goal, unless you have hundreds of columns in the table. Leazy loading makes a big difference when featching collections.
To find out if it's lazy loaded or not without checking the generated sqls you can simply close the session and then access the property.
However, you need further bytecode enhancement to enable this type of behavior. http://docs.jboss.org/hibernate/orm/5.0/manual/en-US/html_single/#performance-fetching-lazyproperties
For instance, after enhancing the bytecode to enable lazy loading of horse (string property) inside Note and running.
Criteria criteria = session.createCriteria(Note.class);
List<Note> list1 = criteria.list();
session.close();
String horse = list1.get(0).getHorse();
I get
Caused by: org.hibernate.LazyInitializationException: Unable to perform requested lazy initialization [stackoverflow.Note.horse] - no session and settings disallow loading outside the Session
at org.hibernate.bytecode.enhance.spi.interceptor.Helper.throwLazyInitializationException(Helper.java:165)
You can use the config hibernate.show_sql=true and view the output SQL.

hibernate version property mapping in reverse engineering file

I'm working on application that uses 66 tables (SQL Server 2012). Already, hibernate refuses to recognise the "identity" property set for each id column, so I have to put in the <table> element below in my reverse engineering to fix that, just in case I have to re-map my table after making changes to them in SQL Server 2012:
<table name="EMPLOYEE">
<primary-key>
<generator class="identity"/>
</primary-key>
</table>
The question is, I want to do the same for the version property without having to go into all 66 hbm.xml files to add <version name=”version” type=”long” /> every time I map my tables.
Is there a way to set something in the reverse engineering or somewhere else so that hibernate automatically adds the version property?
Thanks
Figured this out. The answer is to ensure that your versioning column in your db is called "version" and hibernate will automatically set the versioning in the xml mapping for you.

How to use Struts 2 push tag for form input fields?

I have two classes one is Action class MyAction and other is POJO class User. Inside MyAction, i have made getter-setter for User class.
Then I have index.jsp page for user input. In this, I am using struts 2 push tag for the properties stored in User class. It looks something like this:
<s:form action="go" method="post">
<s:push value="user">
<s:textfield name="id" label="usr-id"/> <!-- user.id -->
<s:textfield name="fname" label="first-name"/> <!-- user.fname -->
</s:push>
<s:submit/>
<s:token/>
</s:form>
But I am getting an error. If I remove the push tag and prefix the User properties with user, then it runs fine. Can any one guide me, where I am wrong and how to use push tag for input fields in form.
No matter if you use <s:push>, <s:set/>, <s:iterator> with its var or IteratorStatus attributes... :
to show a value, any way is a good way;
to send a value, the only way is specifying the full "path" in the name attribute.
For example, you can use the pushed object in the value attribute, but to make it work when submitting, you still need to put the user in name attribute:
<s:push value="user">
<s:textfield name="user.id" value="id" /> <!-- user.id -->
<s:textfield name="user.fname" value="fname"/> <!-- user.fname -->
</s:push>
This makes the use of <s:push> in your case totally useless.
But in an use-case where source and destination differs, eg. you read user.fname from ActionSource, and send its value to ActionDestination in a selectedFname String, the jsp would be
<s:push value="user">
<s:textfield name="selectedId" value="id" /> <!-- user.id -->
<s:textfield name="selectedFname" value="fname"/> <!-- user.fname -->
</s:push>
So it would have done "something usefull".
But basing on my experience, you won't pretty much never use push. If you need it, your data structure is probably too complex.
Your code looks like ok, but to send values from textfields you need to push the user object to the stack again. Better do it with some interceptor before the params interceptor populates the action. The same thing is doing modelDriven interceptor.
The Model-Driven interceptor watches for ModelDriven actions and adds the action's model on top of the value stack.
Note: The ModelDrivenInterceptor must come before the both StaticParametersInterceptor and ParametersInterceptor if you want the parameters to be applied to the model.
Note: The ModelDrivenInterceptor will only push the model into the stack when the model is not null, else it will be ignored.
You can use model driven approach it's pushing a model for the view and for the controller. The last is missing from your code.
The example of using ModelDriven approach.
Push is not a ui tag. Push is used for put objects into top of value stack. If your object is not in top of stack you get your values by using object.attributname. If your object is in the value stack, you can access it directly attributename.

Separately managing obiects from lists in spring 3 mvc + jsp web application

After thinking a lot, this is the best question title I could find. Not that representative, I'm sorry :-(.
By the way let me explain the problem.
I have to implement an administration panel. It displays a table where every line contains a user with his roles and account status. You can see the idea sketched in the following image
now, my problem is about managing the backing model object:
I have to pass a list of users to populate the administration panel but
I have to bind each user to a model object and
I have to submit each user separately.
I found many tips for managing the table as a whole so that a single button submits all the users at the same time, but what I want to do is populating the table with a list and managing every list record (the user) separately.
I thought to manage each line with javascript to keep trace of the modified values and to use them to build a uri like http://authority/app/user_management/{user_id}/{is_locked}/{is_admin}/.../. The uri will be triggered by the corresponding submit button, but I prefer to avoid this approach.
Moreover, to populate the table with the correct checkbox value it is necessary to have a binding enstablished.
Any advice?
Thanks!
I think you can use separate form for each row with a User object as a Model. You will have simple 'updateUser' handler with User object in input parameters list.
As I remember it could be a User you are iterating through in your foreach, but I need to check it with the real example..) At least you can use simple form and pass 'id', 'isLocked', etc. as request parameters.
<!-- Inside foreach loop -->
<form action="/updateUser" method="POST">
<input type="hidden" name="id" value="${user.id}"/>
<tr>
<td><input type="checkbox" name="isAdmin" value="Is Admin" checked="${user.isAdmin}"/></td>
<td><input type="submit" value="Submit"/></td>
</tr>
</form>
And something similar on server side:
#RequestMapping(value = "/updateUser", method = RequestMethod.POST)
#ResponseBody
public ResponseDTO updateUser(#RequestParam String id, #RequstParam boolean isAdmin) {
// your update logic
}

Categories

Resources