How to fix jpa one to many - spring

Need to fetch data from one table to another.I performed jpa one to many mapping. But id cannot fetched. Where is my mistake?
I have tried mapping using one to many and many to one concepts but can't able to fetch data from one table to another
User.java
#Entity
#Table(name = "users")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "User_ID")
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
private String firstName;
private String lastName;
private Long phoneNumber;
#NotNull(message="Password is compulsory")
#Email(message = "Email is invalid")
private String email;
private String password;
#OneToMany(mappedBy="user", cascade = CascadeType.ALL)
Set<Data> data = new HashSet<Data>();
public Set<Data> getData() {
return data;
}
public void setData(Set<Data> data) {
this.data = data;
}
public User() {
super();
}
Data.java
#Entity
#Table(name = "data")
public class Data implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "DataID")
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
#ManyToOne(fetch = FetchType.EAGER,cascade= CascadeType.ALL)
#JoinColumn(name = "User_ID")
private User user;
public Data() {
super();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
DataController.java
#PostMapping("/data/{userId}")
public Data createData(
#PathVariable(value= "userId") String userId,
#Valid #RequestBody Data data) {
return userRepository.findById(userId).map(user -> {
data.setUser(user);
return dataRepository.save(data);
}).orElseThrow(() -> new ResourceNotFoundException("userId" + userId +
"not found"));
}
Results in no error but can't able to fetch user id

Related

Hibernate JPA loop

I created an entity class :
#Entity
#Table(name="users")
#Getter #Setter
public class UserModel implements Serializable {
#Setter(AccessLevel.NONE)
#Getter(AccessLevel.NONE)
private static final long serialVersionUID = -5608230793232883579L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(nullable = false, unique = true)
private String userId;
#Column(nullable = false, length = 50)
private String firstName;
#Column(nullable = false, length = 50)
private String lastName;
#Email
#Column(nullable = false, length = 120, unique = true)
private String email;
#Column(nullable = false)
private String encryptedPassword;
private Boolean emailVerificationStatus = false;
private String emailVerificationToken;
#ManyToMany(cascade= { CascadeType.PERSIST }, fetch = FetchType.EAGER )
#JoinTable(
name = "user_role",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns=#JoinColumn(name = "role_id", referencedColumnName = "id"))
private List<RoleModel> roles;
#JsonManagedReference
#OneToMany(mappedBy = "user")
private List<ProjectModel> projects;
}
For the list of projects, I also have an entity class:
#Entity
#Table(name= "projects")
#Getter #Setter
public class ProjectModel implements Serializable {
#Setter(AccessLevel.NONE)
#Getter(AccessLevel.NONE)
public static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(nullable = false, unique = true)
private String projectId;
// ...
#Column
#JsonManagedReference
#OneToMany(mappedBy = "project")
private List<ObjectiveModel> objectives;
// ...
#JsonBackReference
#ManyToOne(
cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH },
fetch = FetchType.LAZY
)
private UserModel user;
}
I also use a DTO layer to communicate with database:
#Getter #Setter
public class UserDto implements Serializable {
#Setter(AccessLevel.NONE)
#Getter(AccessLevel.NONE)
private static final long serialVersionUID = -5352357837541477260L;
// contains more information than models used for rest
private long id;
private String userId;
private String firstName;
private String lastName;
private String email;
private String password;
private String encryptedPassword;
private String emailVerificationToken;
private Boolean emailVerificationStatus = false;
private List<String> roles;
private List<ProjectDto> projects;
}
Each entity has its own Dto equivalent. I can create a user. My issue is trying to log in. My userServiceImpl implements Spring Security UserService. Here is my implementation :
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
UserModel userModel = userRepository.findByEmail(email);
if(userModel == null)
throw new UsernameNotFoundException("User with email " + email + " not found");
return new UserPrincipalManager(userModel);
}
My UserPrincipalManager :
public class UserPrincipalManager implements UserDetails {
private static final long serialVersionUID = 7464059818443209139L;
private UserModel userModel;
private ProjectModel projectModel;
#Getter #Setter
private String userId;
#Autowired
public UserPrincipalManager(UserModel userModel) {
this.userModel = userModel;
this.userId = userModel.getUserId();
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new HashSet<>();
Collection<AuthorityModel> authorityModelEntities = new HashSet<>();
// get user roles
Collection<RoleModel> roleModels = userModel.getRoles();
if (roleModels == null) {
return authorities; // null
}
// get user roles
roleModels.forEach((role) ->{
authorities.add(new SimpleGrantedAuthority(role.getName()));
authorityModelEntities.addAll(role.getAuthorities());
});
// get user authorities
authorityModelEntities.forEach(authorityModel -> {
authorities.add(new SimpleGrantedAuthority(authorityModel.getName()));
});
return authorities;
}
#Override
public String getPassword() {
return this.userModel.getEncryptedPassword();
}
#Override
public String getUsername() {
return this.userModel.getEmail();
}
// we do not store this information in DB
#Override
public boolean isAccountNonExpired() {
return true;
}
// we do not store this information in DB (yet)
#Override
public boolean isAccountNonLocked() {
return true;
}
// we do not store this information in DB (yet)
#Override
public boolean isCredentialsNonExpired() {
return true;
}
// isEnabled depending if account is activated => email verification status value
#Override
public boolean isEnabled() {
return this.userModel.getEmailVerificationStatus();
}
}
While trying to log in a User sql request is looping.
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:31)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:106)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:31)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:106)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:31)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:106)
In the end the application crashes and returns a 403 error.
2020-10-05 12:07:22.215 DEBUG 4564 --- [nio-8080-exec-8] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]
The login fonction works if user do not have project associated.
I don't know anything about model mapper, but I would like to provide you an alternative solution because I think this is a perfect use case for Blaze-Persistence Entity Views.
I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.
A DTO model for your use case could look like the following with Blaze-Persistence Entity-Views:
#EntityView(UserModel.class)
public interface UserDto extends Serializable {
#IdMapping
Long getId();
String getUserId();
String getFirstName();
String getLastName();
String getEmail();
String getPassword();
String getEncryptedPassword();
String getEmailVerificationToken();
Boolean getEmailVerificationStatus();
Set<String> getRoles();
Set<ProjectDto> getProjects();
#EntityView(ProjectModel.class)
interface ProjectDto {
#IdMapping
Long getId();
String getProjectId();
// Other mappings...
}
}
Querying is a matter of applying the entity view to a query, the simplest being just a query by id.
UserDto a = entityViewManager.find(entityManager, UserDto.class, id);
The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
The big bonus here, it will only fetch the columns that are actually needed and it validates the DTO model against your JPA model during boot time, so there are no more runtime surprises!

Not null reference a null or transient value

So i am trying to achieve oneToone relationship between two entity classes.First class is a customer entity class which have two foreign keys buyer_id and seller_id.So what i want initially is that when the user fills the initial credentials in the website the buyer_id and seller_id field should be null and after the user fills the required information for the buyer or seller i will update the row of the corresponding customer and add the buyer_id and seller_id.But when i try to create a customer entry i am getting this error that buyer_id cannot be null?
This is my customer table
#Entity
#Table(name = "Customer")
public class Customer {
public enum Status{
ACTIVE,
IN_ACTIVE
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#OneToOne(fetch = FetchType.LAZY,optional = true,cascade=CascadeType.ALL)
#JoinColumn(name = "seller_id",nullable = true,referencedColumnName = "id",updatable = true)
#Basic(optional = true)
private Seller seller_id;
#OneToOne(fetch=FetchType.LAZY,optional = true,cascade=CascadeType.ALL)
#JoinColumn(name = "buyer_id", nullable = true,referencedColumnName="id",updatable = true)
#Basic(optional = true)
private Buyer buyer_id;
#OneToOne(fetch=FetchType.LAZY,optional = false,cascade = CascadeType.ALL)
#JoinColumn(name = "user_id",nullable = false,unique = true,referencedColumnName = "id")
private User user_id;
public Buyer getBuyer_id() {
return buyer_id;
}
public void setBuyer_id(Buyer buyer_id) {
this.buyer_id = buyer_id;
}
#Column(name = "Name")
String name;
#Enumerated(EnumType.STRING)
#Column(name = "Status")
private Status status;
public Customer(String name,Status status){
this.name=name;
this.status = status;
}
public Customer(){
}
public Seller getSeller_id() {
return seller_id;
}
public void setSeller_id(Seller seller_id) {
this.seller_id = seller_id;
}
public User getUser_id() {
return user_id;
}
public void setUser_id(User user_id) {
this.user_id = user_id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user_id;
}
public void setUser(User user) {
this.user_id = user;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
This is my buyer table
#Entity
#Table(name="Buyer")
public class Buyer {
#Id
#Column(name = "id") private long id;
#Column(name = "GSTIN")
String GSTIN;
#Column(name = "Legal_Document")
#Lob
private byte[] legalDocument;
#OneToOne(fetch=FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "buyer_id")
#JsonIgnore
private Customer customer;
#Column(name = "Authorized_person_name")
String authorized_person_name;
#Column(name = "Authorized_person_email")
String authorized_person_email;
}
This is my seller table
#Entity
#Table(name = "Seller")
public class Seller {
#Id
#Nullable
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "GSTIN")
private String GSTIN;
#Column(name = "GST_Document")
#Lob
private byte[] gst_document;
#OneToOne(fetch=FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "seller_id")
#JsonIgnore
private Customer customer;
// #OneToOne(fetch = FetchType.LAZY,
// cascade = CascadeType.ALL,
// mappedBy = "sellerId")
// #JsonIgnore
// private PickupAddress pickupAddress;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
public String getGSTIN() {
return GSTIN;
}
public void setGSTIN(String GSTIN) {
this.GSTIN = GSTIN;
}
public byte[] getGst_document() {
return gst_document;
}
public void setGst_document(byte[] gst_document) {
this.gst_document = gst_document;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

Persisting data with JPA with existing datas

I want to persist an object like this one :
{
"paymentMode": "CREDIT CARD",
"totalAmount": 158.0,
"orderProducts": [
{
"productKeyId": "HycaR7sPeecIMZEewanuK0jzPo7S33",
"name": "Cornish crab salad, brown crab mayonnaise, toasted muffin",
"price": 20.0,
"qty": 1,
"imgPath": "pathImage",
"category": {
"categoryKeyId": "23ume70Fu6yqyGUWfQkW110P4ko3gZ",
"name": "Starter"
}
},...
],
"seller": {
"userKeyId": "qmNR5g2TD8Ja5KvA1DCQWzYj55nvbP",
"firstName": "David",
"lastName": "Vera",
"email": "david.vera#9online.fr",
"addresses": [
{
"addressKeyId": "2t7x0bFgP5B9Qb2ymnLL5aPZVwMFhJ",
"city": "Vancouver",
"country": "Canada",
"streetName": "123 street name",
"postalCode": "ABCCBA",
"type": "billing",
},...
]
},
"createdAt": "2019-10-22T09:48:06.000+0000"
}
Some object are already stored in Database such as seller, addresses, products and product category.
I created : Orders tables
#Entity
#Table(name="orders")
#Getter #Setter
public class OrderEntity implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true)
private String orderKeyId;
// A sale belong to one seller
#ManyToOne(fetch = FetchType.LAZY)
private UserEntity seller;
private String paymentMode;
private double totalAmount;
#OneToMany(mappedBy = "pk.order")
#Valid
private List<OrderProductEntity> orderProducts;
}
An order_product table (pivot table):
#Entity
#Table(name="order_product")
#Getter #Setter
public class OrderProductEntity {
#EmbeddedId
#JsonIgnore
private OrderProductPK pk;
#Column(nullable = false)
private Integer qty;
// default constructor
public OrderProductEntity() {
super();
}
public OrderProductEntity(OrderEntity order, ProductEntity product, Integer quantity) {
pk = new OrderProductPK();
pk.setOrder(order);
pk.setProduct(product);
this.qty = quantity;
}
#Transient
public ProductEntity getProduct() {
return this.pk.getProduct();
}
...
}
And a product table
#Entity
#Table(name="products")
#Getter #Setter
public class ProductEntity implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String productKeyId;
// many to one relationship with category
#ManyToOne
#JoinColumn(name = "category_id")
private CategoryEntity category;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private double price;
#Column(nullable = false)
private int qty;
private String imgPath;
#JsonManagedReference
#OneToMany(mappedBy = "pk.product", fetch = FetchType.EAGER)
#Valid
private List<OrderProductEntity> orderProducts;
}
The userEntity class :
#Entity
#Table(name = "users")
#Getter #Setter
public class UserEntity implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true)
private String userKeyId;
#Column(nullable = false, length = 50)
private String firstName;
#Column(nullable = false, length = 50)
private String lastName;
#Column(nullable = false, length = 120, unique = true)
private String email;
#Column(nullable = false)
private String encryptedPassword;
private String emailVerificationToken;
// column definition do not work for all database engine. So set the value to false is the same
// #Column(nullable = false, columnDefinition = "boolean default false")
#Column(nullable = false)
private Boolean emailVerificationStatus = false;
// One user can have Many Addresses
#OneToMany(mappedBy = "userDetails", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JsonManagedReference
private List<AddressEntity> addresses;
}
And finally the embedded class :
#Embeddable
#Getter #Setter
#ToString
public class OrderProductPK implements Serializable {
private static final long serialVersionUID = 476151177562655457L;
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "order_id")
private OrderEntity order;
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "product_id")
private ProductEntity product;
...
}
I created a controller method to persist orders in a MySQL database:
public OrderRest createOrder(#RequestBody OrderRequestModel orderRequestModel) throws Exception {
OrderRest returnValue = new OrderRest();
ModelMapper modelMapper = new ModelMapper();
OrderDto orderDto = modelMapper.map(orderRequestModel, OrderDto.class);
OrderDto createdOrder = orderService.createOrder(orderDto);
returnValue = modelMapper.map(createdOrder, OrderRest.class);
// 5. Return the expected object
return returnValue;
}
I have an orderDTO object that contains several fields (including ID).
public class OrderDto implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private Long id;
private String orderKeyId;
private String paymentMode;
private double totalAmount;
private List<ProductDto> orderProducts;
private UserDto seller;
private Date createdAt;
}
My productDTO object
public class ProductDto implements Serializable {
// ommit this member and do not generate getter / setter
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private Long id;
private String productKeyId;
private String name;
private double price;
private int qty;
private String imgPath;
private CategoryDto category = new CategoryDto();
}
The UserDto :
#Getter #Setter
#ToString
public class UserDto implements Serializable {
// ommit this member and do not generate getter / setter
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private long id;
private String userKeyId;
private String firstName;
private String lastName;
private String email;
private String password;
private String encryptedPassword;
private String emailVerificationToken;
private Boolean emailVerificationStatus = false;
private List<AddressDto> addresses;
// private List<RoleDto> roles;
}
the controller is calling my service layer :
#Override
public OrderDto createOrder(OrderDto orderDto) {
// create a new order
ModelMapper modelMapper = new ModelMapper();
OrderEntity orderEntity = modelMapper.map(orderDto, OrderEntity.class);
String orderKeyId = utils.generateOrderKeyId(30);
orderEntity.setOrderKeyId(orderKeyId);
orderEntity.setCreatedAt(orderDto.getCreatedAt());
orderEntity.setPaymentMode(orderDto.getPaymentMode());
orderEntity.setTotalAmount(orderDto.getTotalAmount());
// set the seller
UserEntity userEntity = modelMapper.map(orderDto.getSeller(), UserEntity.class);
orderEntity.setSeller(userEntity);
List<OrderProductEntity> orderProductEntities = new ArrayList<>();
// set the products
for (int i = 0; i < orderDto.getOrderProducts().size(); i++) {
ProductDto productDto = orderDto.getOrderProducts().get(i);
OrderProductEntity orderProductEntity = modelMapper.map(orderDto.getOrderProducts().get(i), OrderProductEntity.class);
orderProductEntities.add(orderProductEntity);
orderDto.getOrderProducts().set(i, productDto);
}
orderEntity.setOrderProducts(orderProductEntities);
OrderEntity storedOrder = orderRepository.save(orderEntity);
OrderDto returnValue = modelMapper.map(storedOrder, OrderDto.class);
return returnValue;
}
I have 3 issues :
I save the order in the database but the seller is not persisted
In the order product table datas are not persisted.
And i obtain an error message in my rest response :
"trace": "org.modelmapper.MappingException: ModelMapper mapping errors: Converter org.modelmapper.internal.converter.CollectionConverter#685b36d6 failed to convert java.util.List to java.util.List.error...

JPA Specification filtering nested object

I am trying to fetch nested object property but getting illegalArgument exception.
AuditTestingPlanSpecification name = new AuditTestingPlanSpecification(new SearchCriteria("auditPlanId.auditPlanEntity", ":",dates));
Page<AuditTestingPlanMaster> a = auditTestingPlanMasterRepository.findAll(name, ten);
Please find below code,
public class AuditTestingPlanSpecification implements Specification<AuditTestingPlanMaster> {
private SearchCriteria criteria;
public AuditTestingPlanSpecification(SearchCriteria searchCriteria) {
this.criteria = searchCriteria;
}
#Override
public Predicate toPredicate(Root<AuditTestingPlanMaster> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
if (root.get(criteria.getKey()).getJavaType() == String.class) {
return builder.like(root.<String>get(criteria.getKey()), "%" + criteria.getValue().get(0).toString() + "%");
} else {
return builder.equal(root.get(criteria.getKey()), criteria.getValue().get(0).toString());
}
return null;
}
}
Class SearchCriteria.java
public class SearchCriteria {
public SearchCriteria(String key, String operation, List<Object> value) {
super();
this.key = key;
this.operation = operation;
this.value = value;
}
private String key;
private String operation;
private List<Object> value;
// getters & setters
}
Class AuditTestingPlanMaster.java
#Entity
#Table(name = "audit_testing_plan_master")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class AuditTestingPlanMaster implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#Column(name = "risk_area_id")
private Long riskAreaId;
#Column(name = "expected_revert_date")
private Instant expectedRevertDate;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private Instant lastModifiedDate;
#JoinColumn(name = "audit_plan_id", referencedColumnName = "id")
private AuditPlanMaster auditPlanId;
//getters & setters
}
Class AuditPlanMaster.java
#Entity
#Table(name = "audit_plan_master")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class AuditPlanMaster implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#Column(name = "remarks", length = 255)
private String remarks;
#Column(name = "audit_plan_entity", length = 50)
private String auditPlanEntity;
#Column(name = "start_date")
private Instant startDate;
#Column(name = "end_date")
private Instant endDate;
//getters & setters
}
I want to fetch all the AuditTestingPlanMaster objects whose AuditPlanMaster.auditPlanEntity string is matching with provided filter value.
Thank you for your time and help in advance.
I had the same problem, here is a snippet of how I handled it. My problem was when accessing id field from inner usuario object, in my case, id would be like your auditPlanEntity, and usuario would be like auditplanMaster:
public static Specification<UsuarioErrorEquipo> usuarioContains(String codigoUsuario) {
return (root, query, builder) -> {
Path<Usuario> u = root.get("usuario");
return builder.equal(u.get("id"), codigoUsuario);
};
}
I believe, that in your case it should be something like:
Path<AuditPlanMaster> u = root.get("auditPlanId");
return builder.equal(u.get("auditPlanEntity"), "the value you want to compare");

JPA repository null pointer exception for many to one mapping with composite primary key

Post class
one to many mapping
Composite primary key using id
I am getting null pointer exception when I make get request for getting comments
#Entity
#Table(name = "posts")
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Size(max = 100)
#Column(unique = true)
private String title;
#NotNull
#Size(max = 250)
private String description;
#NotNull
#Lob
private String content;
#NotNull
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "posted_at")
private Date postedAt = new Date();
#NotNull
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "last_updated_at")
private Date lastUpdatedAt = new Date();
#OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
mappedBy = "post")
private Set<Comment> comments = new HashSet<>();
public Post() {
}
public Post(String title, String description, String content) {
this.title = title;
this.description = description;
this.content = content;
}
//getters and setters
}
Comment class
many to one mapping with composite primary keys using #Idclass
#Entity
#IdClass(CommentId.class)
#Table(name = "comments")
public class Comment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Lob
private String text;
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "post_id", nullable = false)
private Post post;
public Comment() {
}
public Comment(String text) {
this.text = text;
}
//getters and setters
}
Id class
CommentId
public class CommentId implements Serializable {
private static final long serialVersionUID = 1L;
private Post post;
private Long id;
public CommentId(Post post, Long id) {
super();
this.post = post;
this.id = id;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result+ ((post == null) ? 0 : post.hashCode());
result = prime * result ;
return result;
}
public boolean equals(Object object) {
if (object instanceof CommentId) {
CommentId pk = (CommentId)object;
return id.equals(pk.id) && post == pk.post;
} else {
return false;
}
}
//getters and setters
}
repositories
PostRepository
CommentRepository
#Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
#Repository
public interface CommentRepository extends JpaRepository<Comment, Long>
{
}
Controller class get request and I am using mysql database
#RestController
#RequestMapping("/demo")
public class Controller {
#Autowired
PostRepository ps;
CommentRepository cs;
#GetMapping("/post")
public List<Post> getAll(){
return ps.findAll();
}
#GetMapping("/comment")
public List<Comment> getAllcom(){
return cs.findAll();
}
}

Resources