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.
Related
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.
I am using spring-data-redis to communicate with database.
I have entity class like below
#RedisHash(value = "employee")
public class Employee
{
#Id
private long id;
#Indexed
private String name;
#Indexed
private int age;
private Address address;
...... ...... ......
}
I want to filter the employees based on age group. For example, age lesser than 35 (age<35). How to achieve this in below repository?
#Repository
public interface EmployeeRepo extends CrudRepository<Employee, Long>
{
public Employee findByName(String name);
}
I dont prefer to load complete data from table and do search using any loop/stream.
I don't think it does. I tried to implement what you tried to do using
#Index
long lastUpdatedOn;
when I checked the redis it gives a key entity:lastUpdatedOn:160.... and I tried searching for it using ZRANGE which gives no results.
I have a super Entity class like this:
#Getter
#Setter
#NoArgsConstructor
public class GenericEntity {
#Id
private Long id;
#JsonIgnore
#CreatedBy
private Long createdBy;
#JsonIgnore
#CreatedDate
private Long createdDate;
#JsonIgnore
#LastModifiedBy
private Long updatedBy;
#JsonIgnore
#LastModifiedDate
private Long updatedDate;
#JsonIgnore
#Version
private Integer version = 0;
}
and a Role class extends from GenericEntity like this:
#Getter
#Setter
#NoArgsConstructor
public class Role extends GenericEntity {
private String name;
private String desc;
private Integer sort;
}
And after that I have interface RoleRepo like this:
#Repository
public interface RoleRepo extends ReactiveCrudRepository<Role, Long>;
In Router function, I have 2 handler methods
private Mono<ServerResponse> findAllHandler(ServerRequest request) {
return ok()
.contentType(MediaType.APPLICATION_JSON)
.body(roleRepo.findAll(), Role.class);
}
private Mono<ServerResponse> saveOrUpdateHandler(ServerRequest request) {
return ok()
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(request.bodyToMono(Role.class).flatMap(role -> {
return roleRepo.save(role);
}), Role.class);
}
The method findAllHandler works fine, but the saveOrUpdateHandler throw exception like this:
java.lang.IllegalStateException: Required identifier property not found for class org.sky.entity.system.Role!
at org.springframework.data.mapping.PersistentEntity.getRequiredIdProperty(PersistentEntity.java:105) ~[spring-data-commons-2.2.0.M2.jar:2.2.0.M2]
at org.springframework.data.r2dbc.function.convert.MappingR2dbcConverter.lambda$populateIdIfNecessary$0(MappingR2dbcConverter.java:85) ~[spring-data-r2dbc-1.0.0.M1.jar:1.0.0.M1]
But when I move
#Id
private Long id;
from GenericEntity class to Role class, the two methods work fine.
Are there any Annations #MappedSuperclass/JPA in Spring Reactive Data like that
I wish the id field in GenericEntity for all extends class
Thanks for your help
Sorry, my English so bad
I had a similar problem and after some search, I didn't find an answer to your question, so I test it by writing code and the answer is spring data R2DBC doesn't need #Mappedsuperclass. it aggregates Role class properties with Generic class properties and then inserts all into the role table without the need to use any annotation.
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
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.