#NotNull in spring boot not working as expected - java

This is my DTO class:
public class AppDTO implements Serializable {
private String appId;
private Date dateCreated;
#AppFeaturesValidation
private Set<AppFeature> appFeatures;
}
The #AppFeaturesValidation validate the content of appFeatures.
This is the AppFeature class:
public class AppFeature {
private String packageId;
#NotNull
private Boolean isEnabled;
#NotNull
private Boolean isDisplayed;
}
When I send to this value null - it gets it.
In the same project, a different type using #NotNull is working.
The same imports for this annotation, just a simpler object:
public class packDTO implements Serializable {
private String packId;
private Date dateCreated;
#NotNull
private Boolean clone;
}

I had to add #Valid for the appFeatures Set, so the validations will be checked for each of the elements.

Related

How to combine data from two reactive streams in project reactor?

I started using Project Reactor recently and I can't work out how to work with nested streams. I want to update data of outer Mono with some data of inner Mono.
#GetMapping("/search")
public Mono<Github> combineGithubData() {
WebClient client = WebClient.create("https://api.github.com");
Mono<Github> data = client.get().uri(URI.create("https://api.github.com/users/autocorrectoff")).retrieve().bodyToMono(Github.class);
data = data.map(s -> {
client.get().uri(URI.create("https://api.github.com/users/Kukilej")).retrieve().bodyToMono(Github.class).map(m -> {
s.setXXX(m.getName());
return m;
});
return s;
});
return data;
}
The field XXX is always returned as null, although I have set it to a value from inner Mono. I'm pretty sure this would work in RxJs. How do I make this work with Project Reactor?
edit:
the code of the Github class
import lombok.*;
#Getter #Setter
#Builder
#ToString
#NoArgsConstructor
#AllArgsConstructor
public class Github {
private String login;
private int id;
private String node_id;
private String avatar_url;
private String gravatar_id;
private String url;
private String html_url;
private String followers_url;
private String following_url;
private String gists_url;
private String starred_url;
private String subscriptions_url;
private String organizations_url;
private String repos_url;
private String events_url;
private String received_events_url;
private String type;
private boolean site_admin;
private String name;
private String company;
private String blog;
private String location;
private String email;
private String hireable;
private String bio;
private int public_repos;
private int public_gists;
private int followers;
private int following;
private String created_at;
private String updated_at;
private String XXX;
}
Your inner stream is not getting subscribed to. Either us flatMap, or better yet, use zip:
data
.zipWith(client.get().uri(...).retrieve().bodyToMono(Github.class))
.map(tuple2 -> {
//update tuple2.getT1() with m.getName() and return the updated tuple
return tuple2.mapT1(tuple2.getT1().setXXX(tuple2.getT2().getName()));
})
.map(tuple2 -> tuple2.getT1() //updated s);
zipWith() subscribes to the inner stream.

How can I sort List<Object> CRUD Repository

I'm trying to build simple REST for purchases I need 2 methods. The first method should show all purchases sorted by date. The second one removes all purchases for specified date I made a method to add and to get all purchases. Now I'm stuck.
#Entity
#Table (name="purchase")
public class Purchase {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#CreationTimestamp
#Temporal(TemporalType.DATE)
#Column(name="createat")
private Date created;
#Column(name="price")
private BigDecimal price;
#Column(name="currency")
private String currency;
#Repository
public interface PurchaseRepository extends JpaRepository<Purchase, Long>
{
}
#Service
public class PurchaseService {
#Autowired
private PurchaseRepository purchaseRepository;
public void addPurchase(Purchase purchase) {
purchaseRepository.save(purchase);
}
public List<Purchase> getAllPurchase() {
List<Purchase> purchase = new ArrayList<>();
purchaseRepository.findAll().forEach(purchase::add);
return purchase;
}
}
#RestController
public class PurchaseController {
#Autowired
private PurchaseService purchaseService;
#PostMapping("/purchase")
public void addPurchase(#RequestBody Purchase purchase) {
purchaseService.addPurchase(purchase);
}
#RequestMapping("/purchase")
public List<Purchase> getAllTopics() {
return purchaseService.getAllPurchase();
}
}
What I need:
1. method to sort my List sorted by date
2. method that removes all purchases for specified date
You can use Spring Data JPA features in these cases.
Add the following methods to PurchaseRepository:
List<Purchase> findAllByOrderByCreatedAsc();
long deleteByCreated(Date created);
And after all, Spring is going to generate an appropriate query based on a method name.
I got it
long deleteByCreated(Date date);
#Transactional
public long deleteAllByDate(Date date){
return purchaseRepository.deleteByCreated(date);
}
#RequestMapping(method=RequestMethod.DELETE, value="/purchasess/{date}")
public long findAllByCreatedBetween(#DateTimeFormat(pattern="yyyy-MM-dd")
#PathVariable Date date){
return purchaseService.deleteAllByDate(date);
}

How to use jooq codegen to automatically add custom fields to build pojos?

I use jooq codegen to generate entity classes like this :
public class TCoactivitiesPinan extends BaseEntity implements Serializable {
private static final long serialVersionUID = 2007524284;
private Integer id;
private String openid;
private String tel;
private Timestamp createdtime;
...}
but,I want it to automatically determine that if it's a time type, it automatically adds two fields. like this
public class TCoactivitiesPinan extends BaseEntity implements Serializable {
private static final long serialVersionUID = 2007524284;
private Integer id;
private String openid;
private String tel;
private Timestamp createdtime;
private String createdtime_start; // 创建时间_开始时间
private String createdtime_end; // 创建时间_结束时间
private Integer checkstate;
...
}
Is there any way to solve it? ths.
You can implement your own code generator and extend the POJO's "custom code section" as documented here:
https://www.jooq.org/doc/latest/manual/code-generation/codegen-custom-code
Essentially, just write a class like this:
public class MyGenerator extends JavaGenerator {
#Override
protected void generatePojoClassFooter(TableDefinition table, JavaWriter out) {
for (ColumnDefinition column : table.getColumns()) {
if (column.getType().getType().equals("TIMESTAMP")) {
out.tab(1).println("private String %s_start; // 创建时间_开始时间",
getStrategy().getJavaMemberName(column, Mode.POJO));
out.tab(1).println("private String %s_end; // 创建时间_结束时间",
getStrategy().getJavaMemberName(column, Mode.POJO));
}
}
}
}
And then, configure it as follows:
<configuration>
...
<generator>
<name>com.example.MyGenerator</name>
...
</generator>
</configuration>
Of course, the above solution will only generate the desired members, it will not generate any logic to populate those members when you use the generated POJO type.

JPA: Pass default parameter into findAll() method

I have several entities and jpa repositories to them. It looks like:
Event:
public class Event{
#Column
private String name;
#Column
private String description;
}
Place:
public class Place{
#Column
private String name;
#Column
private String description;
#Column
private Double lon;
#Column
private Double lat;
}
And repositories to them:
public interface EventRepository extends JpaRepository<Event, String>, JpaSpecificationExecutor<Event> {
}
public interface PlaceRepository extends JpaRepository<Place, String>, JpaSpecificationExecutor<Place> {
}
It work well. But then I added one else field in each entity calls tenantId
Event:
public class Event{
#Column
private String tenantId;
#Column
private String name;
#Column
private String description;
}
Place:
public class Place{
#Column
private String tenantId;
#Column
private String name;
#Column
private String description;
#Column
private Double lon;
#Column
private Double lat;
}
But all my service works with method findAll(). So, the question is:
How can I get from "old" method findAll() entities only with tenantId = "1" or "2", doesnt matter? It should be work like findAllByTenantId(String tenantId) but it should be 'findAll()'. Can I inject somehow into 'findAll()' tenantId params?
Thx.
Try to override the implementation :
public interface EventRepository extends JpaRepository<Event, String>, JpaSpecificationExecutor<Event> {
List<Event> findAll(String tenantId); // findAllByTenantId
}
JPA criteria API translates into the following query:
select e from Event e where e.tenantId = ?1
And
public interface PlaceRepository extends JpaRepository<Place, String>, JpaSpecificationExecutor<Place> {
List<Place> findAll(String tenantId); // findAllByTenantId
}
JPA criteria API translates into the following query:
select p from Place p where p.tenantId = ?1

Hibernate validation on static inner classes

Can you not validate static inner classes using hibernate validation? I have the following form:
public class Thing {
#NotNull // WORKS!
private String message;
private someClass obj1;
private someOtherClass obj2;
public static class someClass
{
#NotNull //DOES NOT WORK
private String someField;
}
public static class someOtherClass
{
#NotNull //Does NOT WORK
private String someOtherField;
}
}
I got it, you need to mark #Valid on the instances of the someClass and someOtherClass. This fixed the issue for me. Looks like the #Valid annotation I had on my controller for my Thing object wasn't applying recursively to the state of its nested objects.
You can use #Valid on the address property in a combination of other constraints inside Address class. A valid example would be:
public class Person {
#NotEmpty
private String fullName;
#Email
private String email;
#Pattern (regexp = "[0-9]+")
private String telNo;
#NotNull
#Valid
private Address address;
}
class Address {
#NotEmpty
private String houseNumber;
#NotEmpty
private String streetName;
private String province;
private String country;
}

Categories

Resources