springboot keeps coming to an null value - spring

public Account(BaseEntityBuilder<?, ?> b, String email, String name, String nickname, String pwd, UserRole usertype,
String userf1, String userf2, String userf3, String userf4, String userf5, String filetype) {
super(b);
this.email = email;
this.name = name;
this.nickname = nickname;
this.pwd = pwd;
this.usertype = usertype;
this.userf1 = userf1;
this.userf2 = userf2;
this.userf3 = userf3;
this.userf4 = userf4;
this.userf5 = userf5;
this.filetype = filetype;
}
code
public interface SpringReadFileService {
List<Account> findAll();
boolean saveDataFromUploadfile(MultipartFile file);
}
code
List<Account> users = springReadFileService.findAll();
for(int i = 0; i< users.size(); ++i) {
String a = users.get(i).getEmail();
}
code
In this way, I'm trying to get only all email value among the values in the account array, but it keeps coming to an empty value. Can't I bring it like this? I want to get the value of all the emails in the data.

This is how I understand your question:
You are using findAll of a Spring Data JPA repository in order to load all Account instances.
You are only interested in the non empty email addresses.
Define your repository as
class AccountRepository<Account, Long> { // replace Long with the type of the primary key
#Query("SELECT DISTINCT email FROM Account WHERE email IS NOT NULL")
String findAllEmails();
}
Then use findAllEmails to get the required result.
There are a couple of variants of the JPQL statement depending on what you want:
If you want duplicates or email is unique through some constraint drop the DISTINCT
If you also have empty but not null emails, i.e. emails of length 0 you might want to add AND email <> '' to the query.

Related

What is the best way to save jena Result set in database?

I am creating a Spring web application that queries SPARQL endpoints. As a requirement, I'm supposed to save the query and the result for later viewing and editing. So far I have created some entities (QueryInfo, Result, Endpoint) that I use to save the information entered about the Query and the Result. However I'm having trouble with saving the actual results themselves
public static List<String> getSelectQueryResult(QueryInfo queryInfo){
Endpoint endpoint = queryInfo.getEndpoint();
Query query = QueryFactory.create(queryInfo.getContent());
List<String> subjectStrings = query.getResultVars();
List<String> list = new ArrayList();
RDFConnection conn = RDFConnectionFactory.connect(endpoint.getUrl());
QueryExecution qExec = conn.query(queryInfo.getContent()) ; //SELECT DISTINCT ?s where { [] a ?s } LIMIT 100
ResultSet rs = qExec.execSelect() ;
while (rs.hasNext()) {
QuerySolution qs = rs.next();
System.out.println("qs: "+qs);
RDFNode rn = qs.get(subjectStrings.get(0)) ;
System.out.print(qs.varNames());
if(rn!= null) {
if (rn.isLiteral()) {
Literal literal = qs.getLiteral(subjectStrings.get(0));
list.add(literal.toString());
} else if (rn.isURIResource()) {
Resource subject = qs.getResource(subjectStrings.get(0));
System.out.println("Subject: " + subject.toString());
list.add(subject.toString());
}
}
}
return list;
}
My Result entity looks like this:
#Entity #Data #Table(schema = "sparql_tool") public class Result {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(length = 10485760)
private String content;
#OneToOne
#JoinColumn(name = "query_info_id",referencedColumnName = "id")
private QueryInfo queryInfo;
#Column(length = 10485760)
#Convert(converter = StringListConverter.class)
private List<String> contentList;
public Result() {
}
public Result(String content, QueryInfo queryInfo, List<String> list) {
this.content = content;
this.queryInfo = queryInfo;
this.contentList=list;
}
}
I used to save the actual results in the List contentList attribute. However, this only works when the query has only one result variable. If I have multiple result variables I have a table instead of a list. What is the best way to save this result in DB?
I'm working with an SQL DB if that is relevant. Thank you so much in advance!

Spring boot application not accepting ID of incoming POST request

I have an existing system that uses string based unique IDs for users and I want to transfer that System into a Spring boot application. I want to creat a user so I send a POST request with the following content:
As you can see, the id gets ignored.
This is my Spring code for the user class:
#PostMapping("/user")
ResponseEntity addUser(User receivedUser) {
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
logger.info("Empfangener User: " + receivedUser.toString());
try {
User mailCheckUser = userService.getUserByMail(receivedUser.getEmail());
User nameCheckUser = userService.getUserByName(receivedUser.getUsername());
if (mailCheckUser != null){
return new ResponseEntity("Email already exists", HttpStatus.NOT_ACCEPTABLE);
}
if (nameCheckUser != null){
return new ResponseEntity("Username already exists", HttpStatus.NOT_ACCEPTABLE);
}
userService.addUser(receivedUser);
} catch (Exception userCreationError) {
return new ResponseEntity(receivedUser, HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity(receivedUser, HttpStatus.OK);
}
public void addUser(User user) {
userRepository.save(user);
}
And this is my user class:
#Entity
#Table
public class User {
#Id
#Column(unique =true)
private String id;
private #Column(unique =true)
String username;
private #Column(unique =true)
String email;
private #Column(unique =true)
String simpleAuthToken;
private
String password;
/*REDACTED*/
private
boolean isBlocked;
public User(String id, String name, String email, boolean isBlocked) {
this.id = id;
this.username = name;
this.email = email;
this.simpleAuthToken = simpleAuthToken;
this.isBlocked = false;
}
public User() {
}
/*GETTERS AND SETTERS ARE HERE, BUT I CUT THEM FOR SPACING REASONS*/
}
And this is the Spring Output:
My expected outcome would be that Spring would recognize the id and then create a user with the id I provided. Why is the id always null?
EDIT: If I put the ID in a Put or Get Mapping as Path variable, like so:
#PutMapping("/user/{id}")
ResponseEntity updateUser(#PathVariable String id, User receivedUser) {}
then it gets read and recognized, but it will still be null in the receivedUser
First add #RequestBody in the post request body. In the Post request (/test/user) your passing some params but in the method level not received.
If you want receive id from postman then add #RequestParam("id")String id in the method level.
How you generating unique Id by manually or some generators?
And double check user id at the database console level.

how to allow filter in cassandra with java datastax

I created a table and two indexes on it i am not able to do filter query from my spring application
first i created table
CREATE TABLE keyspace.favourite_setting (
id uuid,
user_name text,
filter_name text,
columns LIST<FROZEN<columns_def>>,
filters text,
PRIMARY KEY (id)
);
second i added two indexes
CREATE INDEX IF NOT EXISTS user_name_index ON keyspace.favourite_setting (user_name)
CREATE INDEX IF NOT EXISTS filter_name_index ON keyspace.favourite_setting (filter_name);
then i am trying to filter shows me error you must allow filter although i am doing it already...
My Accessory
#Accessor
public interface FavouriteSettingAccessor {
#Query("select * from favourite_setting where user_name =:userName allow filtering " )
Result<FavouriteSetting> getAllByUserName(#Param("userName") String userName );
}
my Service Impl
#Override
public List<FavouriteSetting> getAllFilterNames(String userName) throws Exception {
session = cassandraFactory.getDataSource();
favouriteSettingAccessor =
new MappingManager(session).createAccessor(FavouriteSettingAccessor.class);
return favouriteSettingAccessor.getAllByUserName(userName).all();
}
My Favourite Setting Model
#Table(keyspace = "keyspace", name = "favourite_setting")
public class FavouriteSetting {
#PartitionKey
#Column(name = "id")
private UUID id;
#Column(name = "user_name")
private String userName;
#Column(name = "filter_name")
private String filterName;
#Column(name = "columns")
private List<ColumnsDef> columns;
#Column(name = "filters")
private String filters;
public FavouriteSetting(UUID id, String userName, String filterName,
List<ColumnsDef> columns, String filters) {
this.id = id;
this.userName = userName;
this.filterName = filterName;
this.columns = columns;
this.filters = filters;
}
public FavouriteSetting() {
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getFilterName() {
return filterName;
}
public void setFilterName(String filterName) {
this.filterName = filterName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public List<ColumnsDef> getColumns() {
return columns;
}
public void setColumns(List<ColumnsDef> columns) {
this.columns = columns;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
}
Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING
For the query
#Query("select * from favourite_setting where user_name =:userName ... " )
userName is not part of the primary key, you can set it as a clustering key. For more information you can look here or here.
Please note that there is no alter statement to add a clustering key, you will need to recreate the table with:
CREATE TABLE keyspace.favourite_setting (
id uuid,
user_name text,
filter_name text,
columns LIST<FROZEN<columns_def>>,
filters text,
PRIMARY KEY (id, username)
The index created for the username column is considered one of the antipatterns for indexes, as it will be expected to be unique (and therefore, it will have high cardinality); you can find more information of why this is a problem here
allow filtering should never be used, as explained here you should resist the urge to just add ALLOW FILTERING to it. You should think about your data, your model and what you are trying to do.
It works Now By adding user_name As Cluster Key and ADD To The End of Query ALLOW FILTERING ..
Thanks :)

Spring Boot request body semi-required fields

In our application user can write a message based on user id or screen name.
class Message {
public final Long userId;
public final String screenName;
public final String text;
#JsonCreator
public Message(#JsonProperty(value = "user_id", required = ???) Long userId,
#JsonProperty(value = "screen_name", required = ???) String screenName,
#JsonProperty(value = "text", required = true) String text) {
this.userId = userId;
this.screenName = screenName;
this.text = text;
}
}
Fields userId and screenName can't be optional at same time, one should be provided.
How in Spring Boot to mark that they are semi-required?
This seems like more of a validation concern rather than deserialization.
Create a Validator then put #Valid within the #RequestMapping on the controller.
See more here:
Spring REST Validation Example
From jenkov tutorials:
#JsonValue
The Jackson annotation #JsonValue tells Jackson that Jackson should
not attempt to serialize the object itself, but rather call a method
on the object which serializes the object to a JSON string. Note that
Jackson will escape any quotation marks inside the String returned by
the custom serialization, so you cannot return e.g. a full JSON
object. For that you should use #JsonRawValue instead (see previous
section).
The #JsonValue annotation is added to the method that Jackson is to
call to serialize the object into a JSON string. Here is an example
showing how to use the #JsonValue annotation:
public class PersonValue {
public long personId = 0;
public String name = null;
#JsonValue
public String toJson(){
return this.personId + "," + this.name;
}
}
The output you would get from asking Jackson to serialize a
PersonValue object is this:
"0,null"
So you can use #JsonValue and put your code either to ignore or not from some fields when you try to convert into JSON
#JsonValue
public String toJson(){
//ignore fields or include them here
}
Just throw an IllegalArgumentException. The best case would be to deserialize, then run through a validator though so you separate the concerns of serialization, and domain validation.
class Message {
public final Long userId;
public final String screenName;
public final String text;
#JsonCreator
public Message(#JsonProperty(value = "user_id", required = false) Long userId,
#JsonProperty(value = "screen_name", required = false) String screenName,
#JsonProperty(value = "text", required = true) String text) {
if(userId == null && screenName == null) {
throw new IllegalArgumentException("userId or screenName must be provided.");
}
this.userId = userId;
this.screenName = screenName;
this.text = text;
}
}

Hide certain fields from a spring request body in swagger

The example api below lets users create an object. The user should be able to specify the name field of the Thing object, while the id field should be automatically generated.
Given the setup below, swagger will display both the name and the id field for the request as something the user can enter, as well as displaying both fields as optional. In reality, for the request, name should be required while id should never be entered by the user.
(Note: the object that is returned when creation is successful, should include the generated id field)
I suppose one option would be to create a copy of the Thing object that is identical, except for the lack of the id field ("ThingCreationRequestObject").
Is this an acceptable solution? It seems there should be a way that doesn't require the maintenance of two objects that essentially represent the same thing.
#RequestMapping(value = "/thing", method = RequestMethod.POST)
Thing createThing(#RequestBody Thing thing) {
// add thing to database, including a generated id
// return thing object, now including the generated id
}
public class Thing {
private String id;
private String name;
}
// Swagger
Thing {
id (string, optional),
name (string, optional)
}
You can annotate the id field with #ApiModelProperty(hidden = true) , in this case it will be hidden from swagger, but still if the user entered the id then it will parsed and assigned to the id field so you need also annotate the setter method only of the id with #JsonIgnore
public class Thing {
#ApiModelProperty(hidden = true)
private String id;
private String name;
public String getId() {
return id;
}
#JsonIgnore
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

Resources