Spring Data Persist entity in Log Table before each save() - spring-boot

im working in a spring boot project and i have a requirement to save the old object in a specific table before each new save ; this my man entities:
#Entity
#Table(name="demande")
public class Demande {
#Id
private Long id;
// all properties
}
#Entity
#Table(name="demande_log")
public class DemandeLog {
#Id
private Long id;
// all properties
}
what im trying to do is before each demandeRepository.save(demande);
i want to save the old demande object (current row in database) as DemandeLog in my demande_log table.
do you have any idea how using spring data, i know that there is a listener #PrePersist in JPA.. but i want to do it properly.
Regards.

I recommend using Envers. It is easy to set up and gives you a complete change log.

Related

How to make #Indexed as unique property for Redis model using Spring JPA Repository?

I have a model class that I store in Redis and I use Jpa Repository with Spring java. Normally(not with redis) jpa repository is saving the new data or updates(conditionally) if the given model is already exist in Db. Here, I want to add new item to redis but if it is not already exists on db otherwise update it just like usual Jpa implementation.
Here is my model:
#Getter
#Setter
#RedisHash("MyRecord")
public class MyRecordRedisModel {
private String id;
#Id
#Indexed
private String recordName;
private Date startDate;
private Date endDate;
}
And my repository class is just a normal spring jpa repo as follows:
#Repository
public interface IFRecordRedisRepository extends JpaRepository<IFRecordRedisModel, String> {
Page<IFRecordRedisModel> findAll(Pageable pageable);
}
Unique key must be the name (I totally do not care about uniquiness of the id). Thus, if the name is already exist in Db than do not add it again. I marked it as Indexed but still it is adding same data (with same recordName).
How can I make it unique?
This would require an additional query, but I think this solution would work for you. You can use query by Example to check if there exists a record with that name, and save conditionally, or do something else if it already exists.
IFRecordRedisModel exampleRecord = new IFRecordRedisModel();
exampleRecord.setRecordName(inputRecord.getRecordName());
if (!repository.exists(Example.of(exampleModel)))
repository.save(inputRecord);
else ..... // do something else

Spring Data Rest Does Not Update Default Value in DB

I have a Spring Boot application using Spring Data REST. I have a domain entity called User with a boolean field isTeacher. This field has been already setup by our DBA in the User table with type bit and a default value of 1:
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // This Id has been setup as auto generated in DB
#Column(name = "IS_TEACHER")
private boolean isTeacher;
}
And the User repository:
public interface UserRepository extends CrudRepository<User, Long>{
}
I was able to add a new user by giving the below request and POST to http://localhost:8080/users, a new user was created in the DB having isTeacher value 1:
{
"isTeacher" : true
}
However, when I tried to change IS_TEACHER by giving PATCH (or PUT) and this request:
{
"isTeacher" : false
}
The response showed that "isTeacher" is still true and the value didn't get changed in the table either. Can someone please let me know why this is happening?
The issue is due to #Data annotation of lombok is ignoring if you have a field that start with isXx it generates getters and setters to boolean with isTeacher for getters and setTeacher for setters then you are not able to update correctly your property, if you put "teacher" when updating should work but you should solve this by overriding that setter.
#Setter(AccessLevel.NONE) private boolean isTeacher;
public void setIsTeacher(boolean isTeacher) {
this.isTeacher = isTeacher;
}

auditing filelds in spring data

I'm beginner in java programming. And I try to write simple stand alone application with spring data. To basic example which is here http://spring.io/guides/gs/accessing-data-jpa/ I want to add, auditing mechanism which will store previous values for objects. I want in customer entity, on #PreUpdate store old values in another table, but I do not know how.
#Entity
#EntityListeners(AuditingEntityListener.class)
public class Customer implements Serializable {
...
#Transient
private transient Customer savedState;
#PreUpdate
public void onPreUpdate() {
if (!savedState.firstName.equals(this.firstName)) {
log.info(String.format("first name was modified, new value =%s, old value=%s",this.firstName, savedState.firstName ));
}
}
#PostLoad
private void saveState(){
this.savedState = (Customer) SerializationUtils.clone(this); // from apache commons-lang
}

EclipseLink 2.1.3, Oracle 11g, return PK after persist with container managed persistence

I'm using EclipseLink 2.1.3 with a container managed EntityManager to interface with an Oracle 11g DB.
I want to have an Entity's #Id variable updated immediately after I call persist() on the EM.
What is the correct strategy to do so with an Oracle DB?
None of the examples I've found on this site deal with this problem with container managed persistence.
The Entity looks like this:
#Entity
#Table(name = "ANNOUNCEMENT_DELIVERY_LOG")
public class AnnouncementDeliveryLog implements Serializable {
#Id
private BigDecimal id;
#ManyToOne
#JoinColumn(name = "ANNOUNCEMENT_ID ")
private Announcements announcement;
public AnnouncementDeliveryLog() {
}
}
Do I need to add something like the following?
#Column(nullable = false)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ANNOUNCEMENT_DELIVERY_LOG_SEQ")
#SequenceGenerator(name="ANNOUNCEMENT_DELIVERY_LOG_SEQ", sequenceName="ANNOUNCEMENT_DELIVERY_LOG_SEQ")
To persist the Entity I'm just calling persist(). Do I also need to call flush()?
Yes, you have to provide a #SequenceGenerator annotation in order that JPA automatically assigns a new ID to the entity during persist().
A flush is not necessary.

Spring data jpa : how to retrieve data using #ElementCollection?

Here is a part of Files.java
#Entity(name="files")
public class Files {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
#ElementCollection
private List<String> filenames= new ArrayList<String>();
//<< getter and setter >>
}
it is correctly created the table 'Files' and 'Files_filenames' on mySql
and I can put data there on Controller with it
Files files = new Files();
files.setTitle(ufile.getTitle());
files.setFilenames(Arrays.asList(ufile.getFilename().split(",")));
so far, everything looks ok
However, when I try to get the data from the database, the filename always returns something like 'persistentbag' not ArrayList.
I would like to know how to get ArrayList from the database
I'm using Spring data JPA using Hibernate as a Jpa vendor.
Thanks in advance
PersistentBag is a List (i.e., it implements List), therefore you can use it as a regular List. There is no need to care about actual implementation of that List in this case.

Resources