Spring boot create database view for entity - spring-boot

I have an Entity which is mapped to a database view and I want to avoid spring from creating table for it, I've tried #Immutable annotation but it's not working, also I want the program to create the view for entity from my script file if it's not created.
#Data
#Entity
#Immutable
public class ViewRequest {
#Id
private Long id;
private Date createDate;
private String requestType;
private String customerUser;
private Long customerUserId;
private RequestStatusEnum requestStatus;
}
any help is appreciated.
Thanks

The #Subselect annotation is the only annotation in Hibernate that prevents the creation of the corresponding table for an #Entity:
#Data
#Entity
#Immutable
#Subselect("select * from VIEW_REQUEST")
public class ViewRequest {
#Id
private Long id;
private Date createDate;
private String requestType;
private String customerUser;
private Long customerUserId;
private RequestStatusEnum requestStatus;
}
Special thanks to this answer :
Exclude a specific table from being created by hibernate?
and for the view creation, you should add your script to a file called data.sql in resources folder, and the file would be automatically executed after table updates of hibernate.

Related

I have a field in database which I do not want to map in my spring java model while making a get call

I have a database table in which there is a field which I do not want to map to my model class while making a get call. Is there any annotation to handle this use case?
When persisting Java objects into database records using an Object-Relational Mapping (ORM) framework, we can ignore fields by adding the #Transient annotation to those fields.
#Entity
#Table(name = "Users")
public class User {
#Id
private Integer id;
private String email;
private String password;
#Transient
private Date loginTime;
// getters and setters
}

Spring Data Redis has strange result

I started using spring data redis in my project for temporary storing some data. Redis is new for me, I've never worked something similar to redis before (Key-Value).
So, traditionally I created repository via extending CrudRepository and my #RedisHash is:
#Data
#NoArgsConstructor
#AllArgsConstructor
#RedisHash(value = "employee", timeToLive = 100)
public class RedisEmployee implements Serializable {
#Id
private String id;
#Indexed
private Long employeeId;
private String fullName;
#Indexed
private String date;
#Indexed
private String companyName;
private String phone;
}
So it works fine but I noticed something strange for me, it's result when
I watch GUI.
This is all data when I save with CrudRepository only one "entity"
So, Look how much rows, I just save 1 #RedisHash value, it could be because of #Indexed annotation but anyway it looks very strange for me.
P.S.
I noticed that without #Indexed it's impossible to find anything, for example:
#Repository
public interface RedisEmployeeRepository extends CrudRepository<RedisEmployee, String> {
RedisEmployee findByDateAndCompanyNameAndEmployeeId(String date, String companyName, Long employeeId);
}
so, findByDateAndCompanyNameAndEmployeeId will not return result if I don't have all fields #Indexed. Can't understand it is proper or not.

Updating object with null field in Spring

I'm working with Spring App, so to work with DB I use Spring Data JPA. Firstly I saved an object. And after some time I need to update this object in the table. But at this moment my object contains one field which is null. But I don't want to update this field with null. So my question is how to prevent updating fields with null? Maybe there is an annotation or some property to solve my problem.My entity:
#Entity
#Table(name = "users")
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private Long id;
#NotNull
#Column(name = "user_name")
#Field
private String username;
#NotNull
#Column(name = "user_identity")
private String identity;
#Column(name="user_image")
private String image;
#Column(name="user_joined")
private String date;
#Column(name="user_origin")
private String origin;
#Column(name="user_sub")
private String sub;
I save and update this entity with implementation of JpaRepository:
#Repository
public interface UserRepository extends JpaRepository<User, Long>
it looks like this:
#Autowired
private UserRepository userRepository;
....
userRepository.save(user);
I've saved my object with not null sub-field. And now I want to update some fields of saved entity, but not sub field, which is null in current object. I wonder if there is any possibility to avoid changing user_sub field to null?
You can add #DynamicUpdate annotation to your User class. This will ignore the fields whose values are null. You can simply do like:
//other annotations
#DynamicUpdate
public class User {
// other codes inside class
}
You can follow a good example from Mkyong's site.
Thanks, guys. I found the solution: #Query will help to update fields that I need

Spring data jpa persist nested changes

I have 3 classes:
Record/ Profile / Options
#Entity
#Table(name="Record")
public class Record implements Serializable {
#Id
#GeneratedValue
private int id;
#ManyToOne(cascade=CascadeType.MERGE)
#JoinColumn(name="ProfileId")
private Profile profile;
....
}
#Entity
#Table(name="Profile")
public class Profile implements Serializable {
#Id
#GeneratedValue
private int id;
#ManyToOne(cascade=CascadeType.MERGE)
#JoinColumn(name="OptionId")
private Option option;
....
}
#Entity
#Table(name="Option")
public class Option implements Serializable {
#Id
#GeneratedValue
private int id;
private String name;
....
}
let's say the original option is "50M" and then I change the record1.profile1.option to "10M"
Also when I do record1.setId(null);recordRepository.save(record1);
I want to create an new entry from record1(as a change history).
In this case because the option is nested, the cascade type of merge will not persist the changes happened in profile. Thus when I get the record back, it will still say that recordNew.profile1.option is 50M
But if I change the cascadeType to CascadeType.ALL or CascadeType.PERSISTin the Record class, when I try to save the new entry, it seems Spring Data JPA will complains about detached property as: org.hibernate.PersistentObjectException: detached entity passed to persist: com.test.lalala.profile.Profile
Is there a way that I could fix this?

Spring Data JPA inserting instead of Update

Hi I am new to Spring Data JPA and I am wondering even though I pass the Id to the entity, the Spring data jpa is inserting instead of merge. I thought when I implement the Persistable interface and implement the two methods:
public Long getId();
public Boolean isNew();
It will automatically merge instead of persist.
I have an entity class called User like:
#Entity
#Table(name = "T_USER")
public class User implements Serializable, Persistable<Long> {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "USER_ID")
private Long id;
#Column(name = "CREATION_TIME", nullable = false)
private Date creationTime;
#Column(name = "FIRST_NAME", nullable = false)
private String firstName;
#Column(name = "LAST_NAME", nullable = false)
private String lastName;
#Column(name = "MODIFICATION_TIME", nullable = false)
private Date modificationTime;
And have another class
#Entity
#Table(name = "T_USER_ROLE")
public class UserRole implements Serializable, Persistable<Long> {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long roleId;
#Column(name = "ROLE_NAME")
private String userRole;
}
I have a custom repository called UserRepostory extending JpaReopistory. I am hitting the save for merge and persist as I see the implementation demonstrate that Spring Data Jpa uses above two methods to either update or insert.
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
I have been trying to figure out but didn't get any clue. Maybe you
guys can help.
I ran into this issue, tried to implement Persistable to no avail, and then looked into the Spring Data JPA source. I don't necessarily see this in your example code, but I have a #Version field in my entity. If there is a #Version field Spring Data will test that value to determine if the entity is new or not. If the #Version field is not a primitive and is null then the entity is considered new.
This threw me for a long time in my tests because I was not setting the version field in my representation but only on the persisted entity. I also don't see this documented in the otherwise helpful Spring Data docs (which is another issue...).
Hope that helps someone!
By default Spring Data JPA inspects the identifier property of the given entity. If the identifier property is null, then the entity will be assumed as new, otherwise as not new. It's Id-Property inspection Reference
If you are using Spring JPA with EntityManager calling .merge() will update your entity and .persist() will insert.
#PersistenceContext
private EntityManager em;
#Override
#Transactional
public User save(User user) {
if (user.getId() == null) {
em.persist(user);
return user;
} else {
return em.merge(user);
}
}
There is no need to implement the Persistable interface.

Resources