For persisting data used hibernate with SQLServer. In system every table contains four column.
1. Created User
2. Created Date
3. Modified User
4. Modified Date
From beginning system does not contain any mechanism for entering "modified User" and "modified Date" while insert and update operation.
My Question. is there any way in hibernate to entering modified User and Modified Date without changing every where ?
My question:
1)Is there any way to provide user(inform of Id or bean) to hibernate ?
2)If Yes,How can I tell to hibernate that populate this two columns while doing insert of records?
Thanks for any help.
One way would be to change of your servlets, or rest controllers, or possibly DAO's you are writing.
A second way is to create a DAO, servlet, or rest controller that gets the user object and date and make all of your servlets/daos/controllers extend the one you just made.
It is a pain in the behind but it would be better than setting a single point of context.
Passing security context(user) and date to a DAO is pretty easy to do and would be a lot easier to maintain in the future.
Related
I am writing a web api using Spring and Postgres.
I have a case where I take a Json object item
The uri is /api/item/{itemId}
Request type is PUT
Json:
{
"name":"itemname",
"description":"item description here"
}
So I do (using JdbcTemplate) a SELECT statement to check if the itemId exists and then update if it does.
I would also like to implement a case with partial puts taking Json that look like this::
{
"name":"itemname"
}
OR
{
"description":"item description here"
}
where only the respective fields are updated. In Spring, the variables not present are automatically null.
The way this is implemented now is:
SELECT all columns from the items table
Sequentially check every single expected variable for null and if they are null, replace the null with the value selected from the table in step 1.
UPDATE all columns with the values (none of which should be null if the table has a not null constraint)
Question: How do you do this without == null or != null checks? Is seems to be poor design and involves iterating through every single expected variable for every single PUT request (I will have many of those).
Desired responses (in order of desirability):
There's a way in Postgres where if a null value is input, the column-value is simply not written to the database (and no error is produced)
There is a way to use Spring (and Jackson) to create a Java object with only the provided values and a way to generate SQL and JdbcTemplate code that only updates those specific columns.
Patch is the way of life - implement it
Change the front-end to always send everything
You have two choices when working with the database:
Just update what has changed, doing everything by yourself.
Get Jackson and Hibernate to do it for you.
So let's look at No. 1:
Let's say you're looking right now at the contents of an html form that has been sent back to the server. Take every field in the html form and update only those fields in the database using an SQL statement. Anything that is not in the form will not get updated in your database table. Simple! Works well. You don't need to worry about anything that is not in the form. You can restrict your update to the form's contents.
In general this is a simple option, apart from one problem, which is html checkboxes. If you are doing an update, html checkboxes can catch you out because due to a little design quirk, they don't get sent back to the server if they are unchecked.
No. 2: Perhaps you're looking for Hibernate, which you didn't mention. Jackson will fill a json object for you (must have a record id). Use Hibernate to populate a java class with the existing record, update with the new values Jackson has provided, then you tell Hibernate to merge() it into the existing record in the database, which it will. I also use Roo to create my Hibernate-ready classes for me.
No. 2 is hard to learn and set up, but once you've done sussed it, it's very easy to change things, add fields and so on.
I am busy practicing on designing a simple todo list webapp whereby a user can authenticate into the app and save todo list items. The user is also only able to to view/edit the todo list items that they added.
This seems to be a general feature (authenticated user only views their own data) in most web applications (or applications in general).
To me what is important is having knowledge of the different options for accomplishing this. What I would like to achieve is a solution that can handle lots of users' data effectively. At the moment I am doing this using a Relational Database, but noSQL answers would be useful to me as well.
The following ideas came to mind:
Add a user_id column each time this "feature" is needed.
Add an association table (in the example above a user_todo_list_item table) that associates the data.
Design in such a way that you have a table per user per "feature" ... so you would have a todolist_userABC table. It's an option but I do not like it much since a thousand user's means a thousand tables?!
Add row level security to the specific "feature". I am not familiar on how this works but it seems to be a valid option. I am also not sure whether this is database vendor specific.
Of my choices I went with the user_id column on the todolist_item table. Although it can do the job, I feel that a user_id column might be problematic when reading data if the data within the table gets large enough. One could add an index I guess but I am not sure of the index's effectiveness.
What I don't like about it is that I need to have a user_id for every table where I desire this type of feature which doesn't seem correct to me? It also seems that when I implement the database layer I would have to add this to my queries for every feature (unless I use some AOP)?
I had a look around (How does Trello store data in MongoDB? (Collection per board?)), but it does not speak about the techniques regarding user_id columns or things like that. I also tried reading about this in some security frameworks (Spring Security to be specific) but it seems that it only goes into privileges/permissions on a table level and not a row level?
So the question is whether my choice was appropriate and if there are better techniques to do this?
Your choice is the natural thing to do.
The table-per-user is a non-starter (anything that modifies the database structure in response to user action is usually suspect).
Row-level security isn't really an option for webapps - it requires each user session to have a separate, persistent connection to the database, which is rarely practical. And yes, it is vendor-specific.
How you index your tables depends entirely on your usage patterns and types of queries you want to run. Is 'show all TODOs for a user' a query you want to support (seems like it would be)? Then and index on the user id is obviously needed.
Why does having a user_id column seem wrong to you? If you want to restrict access by user, you need to be able to identify which user the record belongs to. Doesn't actually mean that every table needs it - for example, if one record composes another (say, your TODOs have 'steps', each step belongs to a single TODO), only the root of the object graph needs the user id.
I'm using Spring Roo, and Spring MVC.
I have Set up Spring Security to use a MySQL database and auth using the standard schema, table users, table authority.
What I have is a webapp to take orders from our sales people in the field. Simply they just fill in the form and submit it to the database.
The ROO generated MVC pages are fine to start, but I need to make some changes and I'm not sure exactly how to do it. I'm just getting my feet wet learning java.
What I need is for our sales order form to capture the username, and the submitted record would be tagged with their username, and then filter the view so that the sales person can only see the records that they themselves have submitted.
Also I would like to implement a stylus signature capture at the bottom of the form. I tried to figure out how to use http://thomasjbradley.ca/lab/signature-pad/#howto but I'm getting lost on where to put the code. I assume in src\main\views\salesorders\create.jspx
I understand this part is off-topic to my original post.
You will need a table in your database that holds the order forms. An important part of this table will be each row will need to contain a way to map back to the user that submitted it. This will most likely be easiest to implement with a column that is a foreign key to the user table.
When it comes time to fetch for forms for a specific user, you will need to query the order forms table and use a WHERE clause that restricts the rows to just the current user.
As for your second question, it will likely be more worthwhile for you to ask in another question on stackoverflow, as it doesn't really pertain to the original question at all.
I have an existing application that I am working w/ and the customer has defined the table structure they would like for an audit log. It has the following columns:
storeNo
timeChanged
user
tableChanged
fieldChanged
BeforeValue
AfterValue
Usually I just have simple audit columns on each table that provide a userChanged, and timeChanged value. The application that will be writing to these tables is a java application, and the calls are made via jdbc, on an oracle database. The question I have is what is the best way to get the before/after values. I hate to compare objects to see what changes were made to populate this table, this is not going to be efficient. If several columns change in one update, then this new table will have several entries. Or is there a way to do this in oracle? What have others done in the past to track not only changes but changed values?
This traditionally what oracle triggers are for. Each insert or update triggers a stored procedure which has access to the "before and after" data, which you can do with as you please, such as logging the old values to an audit table. It's transparent to the application.
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:59412348055
If you use Oracle 10g or later, you can use built in auditing functions. You paid good money for the license, might as well use it.
Read more at http://www.oracle.com/technology/pub/articles/10gdba/week10_10gdba.html
"the customer has defined the table structure they would like for an audit log"
Dread words.
Here is how you would implement such a thing:
create or replace trigger emp_bur before insert on emp for each row
begin
if :new.ename = :old.ename then
insert_audit_record('EMP', 'ENAME', :old.ename, :new.ename);
end if;
if :new.sal = :old.sal then
insert_audit_record('EMP', 'SAL', :old.sal, :new.sal);
end if;
if :new.deptno = :old.deptno then
insert_audit_record('EMP', 'DEPTNO', :old.deptno, :new.deptno);
end if;
end;
/
As you can see, it involves a lot of repetition, but that is easy enough to handle, with a code generator built over the data dictionary. But there are more serious problems with this approach.
It has a sizeable overhead: an
single update which touches ten
field will generate ten insert
statements.
The BeforeValue and AfterValue
columns become problematic when we
have to handle different datatypes -
even dates and timestamps become
interesting, let alone CLOBs.
It is hard to reconstruct the state
of a record at a point in time. We
need to start with the earliest
version of the record and apply the
subsequent changes incrementally.
It is not immediately obvious how
this approach would handle INSERT
and DELETE statements.
Now, none of those objections are a problem if the customer's underlying requirement is to monitor changes to a handful of sensitive columns: EMPLOYEES.SALARY, CREDIT_CARDS.LIMIT, etc. But if the requirement is to monitor changes to every table, a "whole record" approach is better: just insert a single audit record for each row affected by the DML.
I'll ditto on triggers.
If you have to do it at the application level, I don't see how it would be possible without going through these steps:
start a transaction
SELECT FOR UPDATE of the record to be changed
for each field to be changed, pick up the old value from the record and the new value from the program logic
for each field to be changed, write an audit record
update the record
end the transaction
If there's a lot of this, I think I would be creating an update-record function to do the compares, either at a generic level or a separate function for each table.
I have mapped several java classes like Customer, Assessment, Rating, ... to a database with Hibernate.
Now i am thinking about a history-mode for all changes to the persistent data. The application is a web application. In case of deleting (or editing) data another user should have the possibility to see the changes and undo it. Since the changes are out of the scope of the current session, i don't know how to solve this in something like the Command pattern, which is recommended for undo functionality.
For single value editing an approach like in this question sounds OK. But what about the deletion of a whole persistent entity? The simplest way is to create a flag in the table if this customer is deleted or not. The complexest way is to create a table for each class where deleted entities are stored. Is there anything in between? And how can i integrate these two things in a O/RM system (in my case Hibernate) comfortably, without messing around to much with SQL (which i want to avoid because of portability) and still have enough flexibility?
Is there a best practice?
One approach to maintaining audit/undo trails is to mark each version of an object's record with a version number. Finding the current version would be a painful effort if the this were a simple version number, so a reverse version numbering works best. "version' 0 is always the current and if you do an update the version numbers for all previous versions are incremented. Deleting an object is done by incrementing the version numbers on the current records and not inserting a new one at 0.
Compared to an attribute-by-attribute approach this make for far simpler rollbacks or historic version views but does take more space.
One way to do it would be to have a "change history" entity with properties for entity id of the entity changed, action (edit/delete), property name, orginal value, new value. Maybe also reference to the user performing the edit. A deletion would create entities for all properties of the deleted entity with action "delete".
This entity would provide enough data to perform undos and viewing of change history.
Hmm I'm looking for an answer to this too. So far the best I've found is the www.jboss.org/envers/ framework but even that seems to me like more work than should be necessary.