I have a simple update query just to check if update query works:
this.openDBTransaction();
Query updateQuery = session.createQuery(
"UPDATE User AS usr SET usr.failedLogins=666 WHERE usr.id='USER_3000'"
);
int result = updateQuery.executeUpdate();
this.closeDBTransaction();
but somehow DB is not update with desired value. result came as 1 so something took place but for sure not update query.
Any clue what is going on?
You should use #Transactional annotation so that the compiler knows that the transaction is manipulating the database, thus permits to perform Data Manipulation queries or it will simply execute it as a Data Definition Language query.
Look at the code snippet below, for example,
#Transactional
public Employee editEmployee(Employee employee) { //employee is the data you got through post
return entityManager.merge(e1);
}
Also, the best practice is to always implement Data Access Object Interface and its implementation and define your queries in the implementation.
I hope this helps.
Related
I'm new in the world of spring and Spring Data.
I've build a user- and permission management system where a user can grant and remove permissions for another user.
I've digged in the docs but I'm not shure how to handle querys where I just want to insert or manipulate Data in a Table.
In the docs query return type table I couldn't find something like a status or a status reporting object.
What I'm looking for is a pattern that allows me to controle is an operation was successfull. Right now I'm using primitives. When everything worked out I get "1" returned but when I query an empty table I get "0". So I need something with more details.
Thank you for guidance and sharing your experience.
EDIT:
Here is a code example:
#Transactional
#Modifying
#Query(value = "DELETE FROM permissions WHERE producerId=:producerId AND comsumerId=:consumerId", nativeQuery = true)
void clearAllPermissions(#Param("producerId") Long producerId,#Param("consumerId") Long consumerId);
The Method is provided by my repository class.
#Repository
public interface PermissionsRepository extends JpaRepository<ProducerConsumerPermissions, Integer>{
.
.
.
}
I call the class from my service layer which is used by my Controller layer.
I guess it'd be nice to know if this operation was successfull so that I can transport the exeption throught the layer till my frontend and throw a message to the user. But when the Table is empty I get a value of false back when I use Integer as return type.
Make your method return int then you know if any records are deleted.
#Transactional
#Modifying
#Query(value = "DELETE FROM permissions WHERE producerId=:producerId AND comsumerId=:consumerId", nativeQuery = true)
int clearAllPermissions(#Param("producerId") Long producerId,#Param("consumerId") Long consumerId);
If there is a problem it will throw and exception anyway. Spring Data throws DataAccessException that you can catch to see what went wrong.
I'm using the following structure to perform db queries:
getHibernateTemplate().execute(new HibernateCallback<List<String>>() {
#Override
public List<String> doInHibernate(Session session) {
Query query = "select * from whatever";
query.setReadOnly(true);
return query.list();
}
}
Some mapping of attributes might occur in the ongoing hibernate session but those tables shouldn't be altered in any way. I've first tried to use evict(object) for those specific entities but readOnly seems like the better way and I'm loading these unmodifiable objects without anything else attached in a separate DAO. I can't touch the hibernate mapping itself, so any changes there aren't an option for me.
Basically my question is:
(1) Does using evict or setting readOnly make any difference in this case?
(2) Is there a neat way to set readOnly(true) for every call in a DAO? I'm afraid that new methods in the future might forget to set the readOnly part and mess up my db.
I have a simple NamedQuery like this
#org.hibernate.annotations.NamedQuery(name="namedQuery",query="update entity set .... where id=:id"
I have a method like this
public void updateField(final Entity entity){
final Session session = currentSession();
final org.hibernate.Query query= session.getNamedQuery("namedQuery")
...loadParameters();
query.executeUpdate();
return;
}
This always works alright but sometimes in this line of code
query.executeUpdate();
Sometimes I see in the console a select from the entity like a full update of the entity. I don't understand why this happens; if I really want to update a simple field why Hibernate updates me all the fields? When this happens the only single update of the namedQuery seems useless because was I think was updated before.
Something like this i see this in the console
Hibernate:
/* update
com.models.Entity */ update
entity
set
BUNCH OF FIELDS
where
ID=?
and later I see what I really want the only field being updated
update
Entity
set
SINGLE_FIELD_UPDATE
where
ID=?
As I mentioned, the full update sometimes appears sometimes do not and sometimes the full update appears twice before the update of the namedQuery being executed!
Why is this? Why does Hibernate fire a full update and something twice the full update before the real field in the namedQuery being executed?
I am missing something?
Please annotate your class with
#org.hibernate.annotations.Entity( dynamicUpdate = true )
see here
I do a simple web-app where user can select checkboxes of items to remove them from database(like mail manager).
So, is there a correct way to do this?
I think to do like this:(in DAO class)
void delete(List<Long> ids){
.....
statement = connection.prepareStatement("DELETE FROM table WHERE id=?");
for (Long id: ids){
statement.setInt(1, id);
statement.executeUpdate();
}
......
or this:(in servlet action class)
DAO dao = new DAO();
for (Long id: ids){
dao.delete(id); // in DAO simple method void delete(long id);
}
are not good. Сan you tell or explain how to do it right?
UPDATE: ok, can someone tell me how to delete records not one by one?
That depends greatly on whether they're supposed to be deleted in a single transaction or not. Imagine that you need to delete 5 records upon a request and the deletion of 3rd record fails with an exception. What exactly should happen with the first two records and the last two records? That's a business requirement which you've to figure out yourself first.
At least, the DAO/service method which you're calling in the servlet should not care about this. It should be able to take a Set of IDs like so (no, not a List since it can contain duplicates):
Set<Long> ids = collectItSomehow();
someService.delete(ids);
Then, in the real JDBC implementation, you could use PreparedStatement#addBatch() to create a batch of statements and PreparedStatement#executeBatch() to execute it. You can find some concrete examples in this answer: Reusing a PreparedStatement multiple times.
for (Long id: ids){
populateArray;
}
Create array (tempArray) from above loop and pass it here.
statement = connection.prepareStatement("DELETE FROM table WHERE id in("+ tempArray+")");
Note: This may cause sql injection if input is not properly validated.
You want to delete the records one by one or selecting more than one record at once?
I have a JPA Query I am executing on the Google App-Engine datastore.
I am building the query using parameters.
After all parameters have been inputted, I wish to view the Query String.
That is, I wish to view the actual query being executed by the datastore.
Is that even possible?
It would really help me in debugging.
To SOLVE the question, assume the following query:
Query query=EM.createQuery("SELECT FROM "
+MyClass.class.getName()+" C WHERE C.field = :arg1");
query.setParameter("arg1", someParam);
if System.out.println(SomeObj) prints 'SELECT FROM MyClass C WHERE C.field = 17'
then the question is solved.
David
That is, I wish to view the actual query being executed by the datastore.
Enabling DEBUG for the DataNucleus.Datastore log category should do it. Check the DataNucleus Logging documentation.
In current DataNucleus you can just call toString() on the JPA Query object to see the single-string form (without parameter substitution). The actual query invoked on the datastore depends on the datastore (obviously), being SQL in the case of RDBMS, and something else in the case of BigTable.