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
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?
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
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
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
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.