When I create product createdDate return correct, but on update createdDate return null, I tried to implements persistable but still not working
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#SuperBuilder
public class BaseEntity implements Persistable<String> {
#MongoId(value = FieldType.OBJECT_ID)
private String id;
#CreatedDate
private Date createdDate;
#LastModifiedDate
private Date updatedDate;
#Override
public boolean isNew() {
return StringUtils.isEmpty(id);
}
}
To get value for createdDate you need to add #EnableMongoAuditing to main spring class
#SpringBootApplication
#EnableMongoAuditing
Related
I have a simple Spring Boot controller with a simple Object, which is annotated with Lombok, when I tried to post data to the controller the object to not serializing.
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#JsonIgnoreProperties(ignoreUnknown = true)
#EqualsAndHashCode(callSuper = true)
#ToString(callSuper = true)
public class Employee extends BaseDomain {
private String firstName;
private String middleName;
private String lastName;
private String email;
private String mobileNo;
#PostMapping
public Employee saveEmployee(Employee employee) {
log.debug("Employee save {}", employee);
return employeeService.saveOrUpdateEmployee(employee);
}
}
#PostMapping
public Employee saveEmployee(#Requestbody Employee employee) {
log.debug("Employee save {}", employee);
return employeeService.saveOrUpdateEmployee(employee);
}
#Requestbody is missing
my auditing works pretty nice but need to change create listener in that way to obtain null values in first update.
#MappedSuperclass
#Getter
#Setter
#ToString
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractEntity{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Version
private int version;
#CreatedBy
private String createdBy;
#LastModifiedBy
private String updatedBy;
#CreatedDate
private LocalDateTime createdAt;
#LastModifiedDate
private LocalDateTime updatedAt;
}
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#ToString
public class TestProfile extends AbstractEntity{
private String username;
}
Right now during create entity, the "updatedBy" and "updatedAt" is also fullfilled with duplicated values from "createdBy" and "createdAt". Should I change my default implementation to #PrePersist and #PreUpdate?
Here is my JpaConfig
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class AuditingConfig`enter code here` {
#Bean
public AuditorAware<String> auditorAware() {
return () -> Optional.of(((UserDetails) SecurityContextHolder
.getContext().getAuthentication().getPrincipal()).getUsername());
}
}
I'm trying to make invoice in my project.to make it, I need to POST all info that I already put in the DB. I'm trying to use #RequestBody using by requestDto but it keep getting null.
#Data
#Getter
public class InvoiceRequestDto {
private String note;
private AddressRequest addressRequest;
private BuyerRequest buyerRequest;
private SellerRequest sellerRequest;
private OrderRequest orderRequest;
other request in InvoiceRequestDto also look like this.
#Data
#Getter
public class BuyerRequest {
private String companyName;
private String email;
private String buyerManager;
private String buyerManagerNumber;
private String faxNumber;
this is service, I debugged in here and getting null from all requestDto in InvoiceRequestDto.
#Transactional
public Invoice postInvoice(InvoiceRequestDto invoiceRequestDto) {
try {
Buyer buyerPost = buyerRepository.findByBuyerManager(invoiceRequestDto.getBuyerRequest().getBuyerManager());
Seller sellerPost = sellerRepository.findBySellerManager(invoiceRequestDto.getSellerRequest().getSellerManager());
OrderItem orderPost = orderRepository.getByOrderNumber(invoiceRequestDto.getOrderRequest().getOrderNumber());
Invoice newInvoice = new Invoice(invoiceRequestDto.getNote(), orderPost, buyerPost, sellerPost);
Invoice saved = invoiceRepository.save(newInvoice);
return saved;
} catch (Exception e) {
e.printStackTrace();
return null;
}
this is controller.
#PostMapping("api/order/new")
public ResponseEntity<Long> postInvoice(#RequestBody InvoiceRequestDto invoiceRequestDto){
Long result = invoiceService.postInvoice(invoiceRequestDto).getId();
return ResponseEntity.ok(result);
this is Invoice Entity.
#Getter
#Entity
public class Invoice extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "invoice_id")
private Long id;
#ManyToOne
#JoinColumn(name = "buyer_id")
private Buyer buyer;
#ManyToOne
#JoinColumn(name = "seller_id")
private Seller seller;
#ManyToOne
#JoinColumn(name = "product_id")
private Product product;
#ManyToOne
#JoinColumn(name = "delivery_id")
private Delivery delivery;
#ManyToOne
#JoinColumn(name = "orderItem_id")
private OrderItem orderItem;
private boolean finalized;
private String note;
#Builder
public Invoice(String note, OrderItem orderPost, Buyer buyerPost, Seller sellerPost){
this.note = note;
this.orderItem = orderPost;
this.buyer = buyerPost;
this.seller = sellerPost;
}
Instead of using external class like this
#Data
#Getter
public class BuyerRequest {
private String companyName;
private String email;
private String buyerManager;
private String buyerManagerNumber;
private String faxNumber;
Try to use inner static classes in your InvoiceRequestDto like below and try again.
#Data
#AllArgsConstructor
#NoArgsConstructor
public class InvoiceRequestDto {
private String note;
private AddressRequest addressRequest;
private BuyerRequest buyerRequest;
private SellerRequest sellerRequest;
private OrderRequest orderRequest;
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class AddressRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class BuyerRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class SellerRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class OrderRequest {
// neccessary fields
}
}
I have a simple problem - but I think "I am standing on the tube".
I have a spring boot rest api with JPA, Modelmapper, Entities and DTOs.
But the mapping doesn't work.
Entities:
#Getter
#Setter
#MappedSuperclass
public class AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
#Getter
#Setter
#Entity(name = "contacts")
public class Contact extends AbstractEntity {
#NotBlank
private String firstName;
#NotBlank
private String lastName;
#Valid
#OneToMany(mappedBy = "contact", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PhoneNumber> phoneNumberList;
}
#Getter
#Setter
#Entity(name = "phone_numbers")
public class PhoneNumber extends AbstractEntity {
#NotBlank
private String label;
#NotBlank
private String number;
#ManyToOne
#JoinColumn(name = "contact_id", referencedColumnName = "id")
#Setter(value = AccessLevel.NONE)
private Contact contact;
}
The DTOs:
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class ContactDTO {
private Long id;
private String firstName;
private String lastName;
List<PhoneNumberDTO> phoneNumberDTOList = new ArrayList<>();
}
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class PhoneNumberDTO {
private Long id;
private String label;
private String number;
}
My ModelMapperConfig:
#Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(AccessLevel.PRIVATE);
return modelMapper;
}
Repo:
public interface ContactRepository extends JpaRepository<Contact, Long{
}
Service (only the create method):
#Override
public ContactDTO createOne(ContactDTO contactDTO) {
Contact contact = modelMapper.map(contactDTO, Contact.class);
contactRepository.save(contact);
return contactDTO;
}
Is this the correct way to persist the Contact with its multiple phonenumbers?
And how can I create a simple mapping?
If i want to persist it, there comes an error:
Column 'contact_id' cannot be null
I am having a problem with JPA auditing and for #Embedded members. Consider the following example scenario:
I set up a test table in an Oracle DB:
CREATE TABLE AUDIT_TEST (
ID NUMBER(38) NOT NULL PRIMARY KEY,
CREATION_DATE TIMESTAMP(6) DEFAULT SYSTIMESTAMP NOT NULL
);
I define a JPA #Entity with auditing:
#Entity
#EntityListeners(AuditingEntityListener.class)
#Table(name = "AUDIT_TEST")
public class AuditTest {
private Long id;
private LocalDateTime creationDate;
#Id
#Column(name = "ID")
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
#CreatedDate
#Column(name = "CREATION_DATE")
public LocalDateTime getCreationDate() { return creationDate; }
public void setCreationDate(LocalDateTime creationDate) {
this.creationDate = creationDate;
}
}
Finally, I enable JPA auditing in my #Configuration:
#SpringBootApplication()
#EnableJpaAuditing()
public class AuditTestApplication {
}
So far so good; when I construct an AuditTest instance, assign it an id and commit, the creationDate column gets populated with the current timestamp as expected.
However, things stop working when I encapsulate the audit column in an #Embeddable:
#Embeddable
public class AuditTestEmbeddable {
private LocalDateTime creationDate;
#CreatedDate
#Column(name = "CREATION_DATE")
public LocalDateTime getCreationDate() { return creationDate; }
public void setCreationDate(LocalDateTime creationDate) {
this.creationDate = creationDate;
}
}
Then I change my entity class to embed the creation date:
#Entity
#EntityListeners(AuditingEntityListener.class)
#Table(name = "AUDIT_TEST")
public class AuditTest {
private Long id;
private AuditTestEmbeddable auditTestEmbeddable = new AuditTestEmbeddable();
#Id
#Column(name = "ID")
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
#Embedded
public AuditTestEmbeddable getAuditTestEmbeddable() {
return auditTestEmbeddable;
}
public void setAuditTestEmbeddable(AuditTestEmbeddable auditTestEmbeddable) {
this.auditTestEmbeddable = auditTestEmbeddable;
}
}
And unfortunately, the auditing is no longer working.
Is anyone here aware of a way to save the auditing functionality while still using #Embedded classes?
Update:
This functionality has been added to Spring Data 2.1 M2 (Lovelace).
https://jira.spring.io/browse/DATACMNS-1274
Spring Data audit annotations in nested (embeddable) classes isn't supported yet. Here's the jira ticket requesting this feature.
However, we could use custom audit listener to set audit information in embeddable classes.
Here's the sample implementation taken from a blog: How to audit entity modifications using the JPA #EntityListeners, #Embedded, and #Embeddable annotations.
Embeddable Audit
#Embeddable
public class Audit {
#Column(name = "created_on")
private LocalDateTime createdOn;
#Column(name = "created_by")
private String createdBy;
#Column(name = "updated_on")
private LocalDateTime updatedOn;
#Column(name = "updated_by")
private String updatedBy;
//Getters and setters omitted for brevity
}
Audit Listener
public class AuditListener {
#PrePersist
public void setCreatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
if(audit == null) {
audit = new Audit();
auditable.setAudit(audit);
}
audit.setCreatedOn(LocalDateTime.now());
audit.setCreatedBy(LoggedUser.get());
}
#PreUpdate
public void setUpdadtedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
audit.setUpdatedOn(LocalDateTime.now());
audit.setUpdatedBy(LoggedUser.get());
}
}
Auditable
public interface Auditable {
Audit getAudit();
void setAudit(Audit audit);
}
Sample Entity
#Entity
#EntityListeners(AuditListener.class)
public class Post implements Auditable {
#Id
private Long id;
#Embedded
private Audit audit;
private String title;
}
With spring-data 2.4.4 the AuditListener works fine with embedded objects, see
documentation spring-data
The minimal version of spring-data is bundled in spring-boot version 2.4.3