getting object by parameter from nested object mongodb spring data jpa - java

I have mongodb collection for following documents:
#Builder
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document
public class Account {
#Id
private String id;
#Indexed(unique=true)
private String username;
#Indexed(unique=true)
private String email;
#Indexed(unique=true)
private String contact;
private ConfirmationTokenDetails confirmationTokenDetails;
}
#Builder
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document
public class ConfirmationTokenDetails {
#Indexed(unique=true)
private String confirmationToken;
private LocalDateTime createdAt;
private LocalDateTime expiredAt;
}
Basically all what I want is just get Account entity by confirmationToken attribut which stores in nested ConfirmationTokenDetails object. I tried do that by using following method
public interface AccountRepository extends MongoRepository<Account, String> {
Optional<Account> findByConfirmationTokenDetails_ConfirmationToken(String token);
}
but it wasn't working for me.

Related

nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():

I am having some problems with Hibernate and the one-to-one mapping.
My DTO class is like this:
CustomerDTO
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class CustomerDTO {
private String nic;
private String name;
private String address;
private String contact;
private ArrayList<UserDTO> user = new ArrayList<>();
UserDTO
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class UserDTO {
private String email;
private String password;
private String role;
private String lastLogged;
}
My entity class is like this
Customer
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class Customer {
#Id
private String nic;
private String name;
private String address;
private String contact;
#OneToOne(mappedBy = "customer", cascade = CascadeType.ALL)
private User user;
User
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class User {
#Id
private String email;
private String password;
private String role;
private String lastLogged;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "cusNIC", referencedColumnName = "nic", nullable = false)
private Customer customer;
}
CustomerControllerClass
#RestController
#RequestMapping("/api/v1/customer")
#CrossOrigin
public class CustomerController {
#Autowired
CustomerService customerService;
#PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity saveCustomer(#RequestBody CustomerDTO dto){
customerService.saveCustomer(dto);
StandradResponse success = new StandradResponse(200, "success", null);
return new ResponseEntity(success, HttpStatus.OK);
}
}
CustomerService class
#Transactional
#Service
public class CustomerServiceImpl implements CustomerService {
#Autowired
CustomerRepo customerRepo;
#Autowired
UserRepo userRepo;
#Autowired
ModelMapper mapper;
#Override
public void saveCustomer(CustomerDTO dto) {
if(!customerRepo.existsById(dto.getNic())){
Customer customer = mapper.map(dto, Customer.class);
customerRepo.save(customer);
for (UserDTO ud : dto.getUser()){
if(!userRepo.existsById(ud.getEmail())){
UserDTO userDTO = new UserDTO(ud.getEmail(),ud.getPassword(),ud.getRole(),ud.getLastLogged());
User user = new User(userDTO.getEmail(), userDTO.getPassword(), userDTO.getRole(), userDTO.getLastLogged(), customer);
//User user = mapper.map(userDTO, User.class);
userRepo.save(user);
}else {
throw new RuntimeException("Email is already exist!");
}
}
}else{
throw new RuntimeException("Customer is already exist!");
}
}
I tried to send these Json value Using postman
{
"nic" : "55665v",
"name" : "anyname",
"address" : "no 20,56 text",
"contact" : "54673453",
"user": [{
"email":"text#gmail.com",
"password":"1234",
"role":"driver",
"lastLogged":"sunday"
}]
}
And each time I am calling my function I get
ids for this class must be manually assigned before calling save(): lk.EasyCarRental.backend.entity.Customer; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): lk.EasyCarRental.backend.entity.Customer
i do not want to auto generate id. I wont to manually input id
Not sure what the purpose of Customer customerNic = customerRepo.findCustomerByNic(dto.getNic()); is, but since you are not showing that, it's hard to say what's going on. Have you tried using just customer which you persisted prior to entering the loop instead?

Ebean doesn't work with jakson annotation in java

I have class:
#Entity
#Data
#Builder(toBuilder = true)
#AllArgsConstructor
#NoArgsConstructor
public class Users extends Model {
#Id
private String id;
private String fullName;
private String country;
private Role role;
public enum Role {
USER;
#Override
#DbEnumValue
public String toString() {
return name().toLowerCase();
}
}
}
It's work good but if I add Jackson annotation #JsonFormat(shape = OBJECT) for enum I have error
#Entity
#Data
#Builder(toBuilder = true)
#AllArgsConstructor
#NoArgsConstructor
public class Users extends Model {
#Id
private String id;
private String fullName;
private String country;
private Role role;
#JsonFormat(shape = OBJECT)
public enum Role {
USER;
#Override
#DbEnumValue
public String toString() {
return name().toLowerCase();
}
}
}
Error:
Caused by: io.ebean.config.BeanNotEnhancedException: Bean class ...Users is not enhanced? Check packages specified in ebean.mf. If you are running in IDEA or Eclipse check that the enhancement plugin is installed. See https://ebean.io/docs/trouble-shooting#not-enhanced
at io.ebeaninternal.server.deploy.BeanDescriptorManager.setEntityBeanClass(BeanDescriptorManager.java:1569)
at io.ebeaninternal.server.deploy.BeanDescriptorManager.createByteCode(BeanDescriptorManager.java:1434)
at io.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1343)
at io.ebeaninternal.server.deploy.BeanDescriptorManager.readEntityDeploymentAssociations(BeanDescriptorManager.java:761)
at io.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:365)
at io.ebeaninternal.server.core.InternalConfiguration.<init>(InternalConfiguration.java:208)
at io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:120)
at io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:36)
at io.ebean.EbeanServerFactory.createInternal(EbeanServerFactory.java:109)
at io.ebean.EbeanServerFactory.create(EbeanServerFactory.java:70)
Use ebean - 12.1.10, jakson - 2.10.1
Can you help me, how I can resolve this problem

SpringBoot MongoDB inherited CreatedDate and LastModifiedDate becoming null

I have a base class for fields that are common in all the models
#Getter
#Setter
public class BaseModel {
#Id
private String id;
#CreatedDate
private Date createdAt;
#LastModifiedDate
private Date modifiedAt;
#Version
private Long version;
}
and other models are inheriting this class, for eg
#Document(collection = "accounts")
#Getter
#Setter
#ToString
public class Account extends BaseModel {
#Indexed(unique = true)
private String name;
}
When I persist account object then i can see createdAt and modifiedAt getting persisted, but when i query the same account object then I am getting createdAt and modifiedAt as null.
I have enabled mongo auditing also.
I have tried TypeAlias also but not working, any suggestion or help would be appreciated

Spring Rest. Eliminate json property at HTTP.POST

I'm trying to exclude the possibility of a json field to be modificated at HTTP.POST operation. This is my class:
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class UserModel {
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long userId;
#NotNull
private String username;
private RoleModel role;
#NotNull
private String email;
#NotNull
private String firstName;
#NotNull
private String secondName;
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Date registrationDate;
}
I want for example the property userId to be accessible only for read (http get).
I've tried with #JsonProperty but it doesn't work, instead it works for the password field. (this property is visible only for write/ post).
Can you please tell me where I'm wrong? or if there is a more elegant way to do that?
Many thanks,
You can achieve such thing with #JsonView annotation:
// Declare views as you wish, you can also use inheritance.
// GetView also includes PostView's fields
public class View {
interface PostView {}
interface GetView extends PostView {}
}
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class UserModel {
#JsonView(View.GetView.class)
private Long userId;
#JsonView(View.PostView.class)
#NotNull
private String username;
....
}
#RestController
public class Controller {
#JsonView(View.GetView.class)
#GetMapping("/")
public UserModel get() {
return ... ;
}
#JsonView(View.PostView.class)
#PostMapping("/")
public UserModel post() {
return ... ;
}
...
}
For more information: https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring

Spring-Data-Neo4j: relationshipEntity return only graphId for nodes.

I am creating an example using Spring-Data-Neo4j . In this, perform CRUD operations, and all operation run successfully. But when i fetch the relationa ship collection from entity, it return only graphId for nodes, and other values are null. Following is my code. If i do something wrong, please correct me.
Entities:
#NodeEntity
#ToString(callSuper=true, exclude={"movies"})
#EqualsAndHashCode(callSuper = true, exclude = {"name", "movies"})
public class Person extends BaseEntity{
#Getter #Setter
#Indexed(unique = true)
private Long id;
#Getter #Setter
private String name;
#Getter #Setter
#RelatedToVia(type = RelationshipTypes.FRIEND, elementClass = FriendsRelationship.class, direction = Direction.BOTH)
private Set<FriendsRelationship> friends;
}
#RelationshipEntity(type=RelationshipTypes.FRIEND)
public class FriendsRelationship extends BaseEntity{
#StartNode
#Getter #Setter
private Person person;
#EndNode
#Getter #Setter
private Person friend;
#Getter #Setter
private String friendsType;
}
Create Relationship:
public FriendsRelationship createRelationshipBetweenPersons(Person person, Person friend,
Class<FriendsRelationship> relationshipEntity, String friendshipType) {
FriendsRelationship relationship = neo4jTemplate.createRelationshipBetween(person, friend, relationshipEntity, friendshipType, true);
neo4jTemplate.save(relationship);
return relationship;
}
Controller:
#RequestMapping(value="find-person-by-id", method=RequestMethod.POST)
public String findPersonById(long id, Model model) {
Person person = personService.findPersonByProperty("id", id);
model.addAttribute("actor", person);
model.addAttribute("personFriends", person.getFriends());
return "person/view-person-detail";
}
In controller, when i fetch the person, the person fetch successfully, but i fetch the friends, it contain start_node with same person object, but end_node contain person object with graphId value only, others values are null.
For solve this problem, we need to add #Fetch annotation at start-node and end-node in FriendsRelationship entity, like as below:
#RelationshipEntity(type=RelationshipTypes.FRIEND)
public class FriendsRelationship extends BaseEntity{
#Fetch #StartNode
#Getter #Setter
private Person person;
#Fetch #EndNode
#Getter #Setter
private Person friend;
#Getter #Setter
private String friendsType;
}
Now the data fetch successfully.

Categories