Is there an annotation that I can apply to a field that when calling createOrUpdate and passing the object that the specific field will not be updated if the object already exists.
The use case is I have a creation date in my object (which is set to current time of Java object creation) but if the object already exists in the database I do not want the date to be updated but would want the other fields updated. Would it be better to do a query on the id (create if it doesn't exist) and then in my code just iterate through the other fields and do updates for any that are different.
Is there an annotation that I can apply to a field that when calling createOrUpdate and passing the object that the specific field will not be updated if the object already exists.
Hrm. No there isn't. One thing you could do is create a class which has the same fields but without the date field. Or you could have a base-class with all of the fields except the date field. Then have a sub-class which adds the date field. Both classes would save to the same table. You would save the one with the date object when you want to use it.
Hope this helps.
I did this by using readOnly attribute.
#DatabaseField(columnName = "last_value_date", readOnly = true)
private Date lastValueDate;
During the update, all readOnly attributes are skipped from update query.
Related
Why using #Transient Annotated will not create corresponding column in database tables...?
#Transient
String getLengthInMeter() { }
if i am not using "#Transient" annotation then LengthInMeter column will be created in database ,but if i using this annotation the corresponding column will not be created in database can any one explain why it will not created i am not Getting actual reason...
i studyed these links
but still not understanding
#Transient as the documentation explains, is meant for the fields that should not be persisted to the database.
Why? Because sometimes we have fields that we need in our class but not applicable in the database.
For example, age is something we need in a Person object but we don't need that to be persisted in the database. All we need is the birthdate to calculate age.
Another example is fullName which we might need for display purposes but we don't save that to the database simply because we just need to concatenate firstName and lastName everytime.
#Transient - Is meant for property/field that are not to be persisted.
It means that the column value/field value will not be saved in the Database.
JPA Transient - JavaDoc
With Transient variable we can stop serializing the required values, but after deserialization we are getting default values of transient variables and we are loosing the original values. So then what is the need of creating transient variable instead we can skip creating the variable itself. If possible how to get the original value of transient variable.
The idea of a transient variable is that there's no meaning to persist its original value in serialized form, since it wouldn't be in a valid state after de-serialization (think, for example, about a member variable that holds an open Socket).
After de-serialization of the object, the transient variable should be initialized by some method call (for example, the getter of that member may initialize it if it's null).
As for the explanation of Why is there a transient keyword? / What is the use of transient variables? I like to point to this question:
Why does Java have transient fields?
It neatly explains that transient variables are used for i.a. for performance reason, say pre-calculating certain values that come from the combination of other values stored in the object. You need them in your code, but they would only take up valuable space when the object is serialized and sent/stored somewhere.
Another use would be, as mentioned by Eran, to store variables in the object that are necessary for it's function but at the same time are for example dependent on the underlying system.
As for How to get the original value of the transient variable?, there is no clean way to do that afaik. Especially if you serialize and object for transfer between two applications there is no way as the data simply does not exist.
Consider very basic scenario Person class
class Person{
private Name
private DOB
private Age}
In this, storing the Name and DOB makes sense, but storing Age doesn't as it always change on a daily basis, so declare it as transient
and it can be always calculated as Current date - DOB, which will give the accurate Age.
First of all transient keyword is used along with instance variables to exclude them from serialization process. if a field is transient its value will not be persisted.
The perfect use of Transient variable can be seen in Hibernate.
For and example in you Database table there are only two column (name and surname)
but in your POJO entity you are having three variable (name , surname and age) in this situation you can make Transient to age field and you can save your entity without any complain as age variable becomes as transient not going to persist.
I am familiar with Hibernate.I have a question.
Lets say I do session.saveOrUpdate(object). If object contains some 'id'(object identifier), then it means update query will be fired if the object is modified.
I want to know how does Hibernate do that i.e. there could be 'n' number of fields in the object.Does Hibernate check each and every field to know if any field is modified(in this case update query to be fired)?
While using use .saveOrUpdate() it will check if the object has no identifier property and if so it will make it persistent by generating it the identifier and assigning it to session.
if the object is already persistent in this session, do nothing if
another object associated with the session has the same identifier,
throw an exception if the object has no identifier property, save() it
if the object's identifier has the value assigned to a newly
instantiated object, save() it if the object is versioned by a
or , and the version property value is the same
value assigned to a newly instantiated object, save() it otherwise
update() the object
From Hibernate Docs
It checks the field(s) mapped as the identifier for the given object, if the object doesn't have an identifier it calls Save() which INSERTS the object, if it does it calls Update() which UPDATES it
Basically in hibernate if you set object with unique identifier any how it is going to update the whole row by calling
session.saveOrUpdate();
or if unique identifier not found it insert the data.
I'm using Play! frameworks CRUD module but I can't figure something out: my database table has a created field which is basically the time that a row was created. I don't want my user to set this, I want to do it in the backend, simply add the current time. I can't figure out how to do this though.
I have made the field invisible using #Hidden but obviously now I can't create new rows because it's value simply isn't set. So where do I do this?
And another question I have: my table also has a column called publish which is another timestamp. The current format for this field in the CRUD form is yyyy-MM-dd. I would like the specify a date as well, and can't figure out how..
Can someone help?
You could use the javax.persistence.PrePersist annotation to set the created date. Put this method in your model:
#PrePersist
public void prePersist() {
created = new Date();
}
you can use custom field rendering in CRUD templates to display the values formatted or using any control you want (i.e.: a jquery date picker for dates).
To hide a value and assign a default value, first of all remove the value from the edit/blank forms of CRUD by removing the field. Then override the _save() method from the entity (be careful with the initial _, you want the _save(), not save()) and set in the code the values you want before calling super._save(). Like this:
/* Return value may differ */
public void _save() {
current = new Date();
super._save();
}
In our base entity class (that all entities derive from), we have, amongst others, 2 methods. One annotatted with #PrePersist which basically just sets the dateCreated, and the other annotated with #PreUpdate which sets the dateUpdated field.
This works perfectly, as we do not wish to set the dateUpdated field on creation. As part of the design, we also make the two methods protected so that other developers don't go and explicitly mess with those two dates (also no setters).
Also, we can easily enough extend any entity to set the dateUpdated field on creation by defining a method on the actual entity and also annotate it with #PrePersist, so this part is covered.
Now, my problem at the moment is that there is a case where we would like to explicitly update the dateUpdated field on an entity, without any data on it changing (basically touch it). Is there an elegant way of doing this? I do not really want to implement a method that changes one of it's fields and then change it back. And we would like to keep having the entities without setter methods for those fields.
Thanks!
Have you tried just changing the dateUpdated field value? I guess this should make the entity modified to Hibernate, and Hibernate would call the #PreUpdate method which would set the dateUpdated field back to the current time:
public void touch() {
this.dateUpdated = -1;
}
Annotate your dateUpdated field with #Version, remove preUpdate callback and use em.lock(entity, LockModeType.WRITE) prior commiting transaction. Remamber that entity needs to be managed in order to force version column to be updated