I am using Spring+Hibernate for my application. I have a few CRUD operations. Before inserting, I need to check if a similar entry is already in the database, if yes it should not be inserted.
For eg: If I am trying to create a Department, before inserting the row, I should check if a department with the same name already exist or not. If yes, the method returns error message.
Now, I know the unique key constraint can be set on the column to do the check. But, I want to know if there is any other way to do this.
The only way I can think of is first fetching all the departments from the database and check against each object.
Please let me know if there is any other way.
The only way I can think of is first fetching all the departments from the database and check against each object.
You don't need to fetch all departments form the database. It should be enough to search the database for the department with the name you want to insert. Since the name should have a unique key anyways it should be fast enough.
If your #Id attribute is department name, then the saveOrUpdate API of Hibernate will check if an object with that id is already present in the DB. If so it will update, else it will create a new entry. Hope this should help you. See this link.
You can try find object from database by "get" method:
Cat cat = (Cat) sess.get(Cat.class, id);
If received object is null, you can add new.
Also for performance better use query with "count" predicate, for avoid whole object loading.
Related
I have a database with table "Customers". I am currently creating a customer application where administrators should be able to create/delete etc customers. so I want to have one safty in case you delete a customers by mistake. My question are, what is the best way to restore a customer if being deleted?
I was thinking of just having an own table for deleted customers but dont know if there are other ways to achive this.
One way to do this is to add a boolean active column to your Customers table
create table Customers (
firstname varchar(20),
secondname varchar(20),
active Boolean default true
);
And then when you select your records
select * from Customers where active = true;
Then, rather than deleting entries from your customers table, you can just set active to false
Use “soft delete”. That means you don’t really ever delete anything, instead have a flag on each row you can toggle to show a customer is not active. Then you can have a view that shows only non-deleted customers that the code not concerned with undeleting can use.
You should be taking database backups.
Backups are your "first line of defense" - against accidental deletions ... and against anything else that could happen (like a hard disk crash, for example. Or a meteor crash.).
Another approach is to assign a [trigger] to any delete (or, for that matter, to "insert" and "update" statements as well). You can prevent deletion (if you wish), and you'll have a record of who tried to delete.
Here is an example: http://rpbouman.blogspot.com/2011/10/mysql-hacks-preventing-deletion-of.html
Finally, the best approach might be to never delete at all: just create a new "status" column. Set the initial value to "ACTIVE", and "deleted" value to "DELETED".
I agree totally with what #paulsm4 wrote.
I would also add that you could consider using Hibernate Envers.
Envers will create new tables that will record the changing state of audited tables.
An approach is to not actually delete the customer and add an additional status column.
In the business layer you will be able to display all users with status != DELETED.
OBS:
If you actually need to delete them from the database, you can make a cron that will scan all customers with status deleted and deletes them after x days.
I would like to know if there is any way of getting a database's identifier for a record through JDBC.
For example, i am querying the database and getting back a ResultSet which i store in a Map. I give an Id to each record based on the order that i retrieve them from the ResultSet.
Now i would like to re-query the Database and be able to correlate the new ResultSet to my already existing records. So, if a record got deleted, ideally, i would be able to just remove it from the Map by using the unique identifier.
My problem here is that i cannot find a unique identifier coming from the RDBMS itself. I tried using the ResultSet.getRowId() but this method is not implemented by all JDBC driver providers.
Could anyone thing of any way to get a get an identifier from the ResultSet that uniqely identifies a record in the Database ?
Thanks.
Ideally, every Record in your database should have an identifier (Primary Key). The best approach is always try to stick to this.
So, if a record got deleted, ideally, i would be able to just remove it from the Map by using the unique identifier.
Maybe clearing the Map and mapping it again would be an option.
Why can't you use the primary key to identify the record?
What is the best/fastest way to check if an Entity exists in a google-app-engine datastore? For now I'm trying to get the entity by key and checking if the get() returns an error.
I don't know the process of getting an Entity on the datastore. Is there a faster way for doing only this check?
What you proposed would indeed be the fastest way to know if your entity exists. The only thing slowing you down is the time it takes to fetch and deserialize your entity. If your entity is large, this can slow you down.
IF this action (checking for existence) is a major bottleneck for you and you have large entities, you may want to roll your own system of checking by using two entities - first you would have your existing entity with data, and a second entity that either stores the reference to the real entity, or perhaps an empty entity where the key is just a variation on the original entity key that you can compute. You can check for existence quickly using the 2nd entity, and then fetch the first entity only if the data is necessary.
The better way I think would just be to design your keys such they you know there would not be duplicates, or that your operations are idempotent, so that even if an old entity was overwritten, it wouldn't matter.
com.google.appengine.api has been deprecated in favor of the App Engine GCS client.
Have you considered using a query? Guess-and-check is not a scalable way to find out of an entity exists in a data store. A query can be created to retrieve entities from the datastore that meet a specified set of conditions:
https://developers.google.com/appengine/docs/java/datastore/queries
EDIT:
What about the key-only query? Key-only queries run faster than queries that return complete entities. To return only the keys, use the Query.setKeysOnly() method.
new Query("Kind").addFilter(Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL, key).setKeysOnly();
Source: [1]: http://groups.google.com/group/google-appengine-java/browse_thread/thread/b1d1bb69f0635d46/0e2ba938fad3a543?pli=1
You could fetch using a List<Key> containing only one Key, that method returns a Map<Key, Entity> which you can check if it contains an actual value or null, for example:
Entity e = datastoreService.get(Arrays.asList(key)).get(key);
In general though I think it'd be easier to wrap the get() in a try/catch that returns null if the EntityNotFoundException is caught.
Consider am using java , struts, hibernate and oracle. How can i prevent duplicate entries stored in database. One way is to make field as Unique . For example i am entering country "USA" in jsp page,USA is already available means how can i prevent it. Please let me know.
Regards,
sara
You should always indeed put a unique constraint on fields which must stay unique. This will, however, lead to a cryptic exception at commit time. If you want to be more user-friendly, you should check if the entry already exists (using a query) before inserting it, and display a useful and readable error message to the user if the entry already exists.
This still allows two concurrent users to check at the same time, then insert at the same time, but it greatly reduces the probability, and the unique constraint makes sure that one of the commits will fail, leaving your database in a consistent state.
Query your database whether it already contains USA or not. If it does, then don't store it. If not, then do.
Add a unique index to your database table on the country column.
Additionally you can annotate the country attribute of your hibernate object with #Column(unique=true).
I am looking for a way to save or update records, according to the table's unique key which is composed of several columns).
I want to achieve the same functionality used by INSERT ... ON DUPLICATE KEY UPDATE - meaning to blindly save a record, and have the DB/Hibernate insert a new one, or update the existing one if the unique key already exists.
I know I can use #SQLInsert( sql="INSERT INTO .. ON DUPLICATE KEY UPDATE"), but I was hoping not to write my own SQLs and let Hibernate do the job. (I am assuming it will do a better job - otherwise why use Hibernate?)
Hibernate may throw a ConstraintViolationException when you attempt to insert a row that breaks a constraint (including a unique constraint). If you don't get that exception, you may get some other general Hibernate exception - it depends on the version of Hibernate and the ability of Hibernate to map the MySQL exception to a Hibernate exception in the version and type of database you are using (I haven't tested it on everything).
You will only get the exception after calling flush(), so you should make sure this is also in your try-catch block.
I would be careful of implementing solutions where you check that the row exists first. If multiple sessions are updating the table concurrently you could get a race condition. Two processes read the row at nearly-the-same time to see if it exists; they both detect that it is not there, and then they both try to create a new row. One will fail depending on who wins the race.
A better solution is to attempt the insert first and if it fails, assume it was there already. However, once you have an exception you will have to roll back, so that will limit how you can use this approach.
This doesn't really sound like a clean approach to me. It would be better to first see if an entity with given key(s) exists. If so, update it and save it, if not create a new one.
EDIT
Or maybe consider if merge() is what you're looking for:
if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance
if there is no persistent instance currently associated with the session, try to load it from the database, or create a new persistent instance
the persistent instance is returned
the given instance does not become associated with the session, it remains detached
< http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html
You could use saveOrUpdate() from Session class.