DynamoDB NullPointerException Error on save - database

Im trying to save info to DynamoDB but im currently getting the error java.lang.NullPointerException: null when using "save" on the AccountHelper class.
I followed the starter guide found on Github; https://github.com/derjust/spring-data-dynamodb
Here is my Model Class;
#DynamoDBTable(tableName = "Users")
public class User {
// #Id
private String _id;
private String bloodGroup;
private String firstName; // DO NOT change this, needs to stay firstName
private String surname;
private String email;
private String password;
private String addressline;
private String postcode;
private String latitude;
private String longitude;
public User() {}
// More Constructors, Getters & Setters
DynamoDB Config Class;
#EnableDynamoDBRepositories(includeFilters = {#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {DynamoDBRepo.class})})
#Configuration
public class DynamoDBConfig {
#Value("${amazon.aws.accesskey}")
private String amazonAWSAccessKey;
#Value("${amazon.aws.secretkey}")
private String amazonAWSSecretKey;
public AWSCredentialsProvider amazonAWSCredentialsProvider() {
return new AWSStaticCredentialsProvider(amazonAWSCredentials());
}
#Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
}
#Primary
#Bean
public DynamoDBMapperConfig dynamoDBMapperConfig() {
return DynamoDBMapperConfig.DEFAULT;
}
#Bean
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig config) {
return new DynamoDBMapper(amazonDynamoDB, config);
}
#Bean
public AmazonDynamoDB amazonDynamoDB() {
return AmazonDynamoDBClientBuilder.standard().withCredentials(amazonAWSCredentialsProvider())
.withRegion(Regions.US_EAST_1).build();
}
}
Here is the method/class where i am getting the error;
#Service
public class AccountHelper {
private DynamoDBRepo dynamoDBRepo;
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
public User create(String bloodGroup, String firstname, String surname, String email, String password, String addressline, String postcode) {
// Getting the error here
return dynamoDBRepo.save(new User(bloodGroup, firstname, surname, email, bCryptPasswordEncoder.encode(password), addressline, postcode));
}
// More methods below that i am not adding to keep this question to a minimum.
Here is my controller;
#Controller
#Component
public class AccountController {
#Autowired
private AccountHelper Service_functions;
#ResponseBody // Works
#PostMapping(value = "/create/{bloodGroup}/{firstname}/{surname}/{email}/{password}/{addressline}/{postcode}")
public String create( #PathVariable String bloodGroup , #PathVariable String firstname, #PathVariable String surname, #PathVariable String email, #PathVariable String password, #PathVariable String addressline, #PathVariable String postcode){
User CreateUser = Service_functions.create(bloodGroup, firstname, surname, email, password, addressline, postcode);
System.out.println("this is working");
return CreateUser.toString();
}
account properties;
spring.application.name=account-service
server.port=8020
eureka.client.service-url.defaultZone=http://localhost:8001/eureka/
amazon.aws.accesskey="" // i removed the keys
amazon.aws.secretkey=""
Any Suggestions/Help would be greatly on where i am going wrong.

Two things you need to fix here based on your details provided.
Add #Autowired annotation on your dynamoDBRepo variable so that it can be recognised as spring managed bean.
Based on your comment
i.e. error saying that it cannot find
com.bdonor.accountservice.Repository.DynamoDBRepo
You need to include com.bdonor.accountservice.Repository package as JPA repository package and enable jpa repository scan in your configuration.

Related

Spring, Angular.js 400 Bad Request

I'm having a hard time figuring out why this request encounter 400 BAD request :
{
email: "ccc#gmail.com"
lastfmUsername: "bluecun"
password: "$2a$10$if246VMeosRCNJibodEhueXGyQNiAHeJd3KVHi7WedjByECYeXO5."
username: "bluecun"
}
Here is my model and controller code :
public class User {
private Long id;
private String username;
private String lastfmUsername;
private String email;
private String password;
...
}
#RequestMapping(value = "/register", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public
#ResponseBody
void register(#RequestBody User user) throws Exception {
semanticGraphDao.saveUser(user);
}
Thanks for the answers.
First you need to check if you JSON is wellformed, which means: properties surrounded by quotes and a colon between each property, for example:
{
"email": "ccc#gmail.com",
"lastfmUsername": "bluecun",
"password": "$2a$10$if246VMeosRCNJibodEhueXGyQNiAHeJd3KVHi7WedjByECYeXO5.",
"username": "bluecun"
}
On the top of that, check the constructor of your User class. It must have a default constructor:
public class User {
private Long id;
private String username;
private String lastfmUsername;
private String email;
private String password;
public User() {
}
// Getters and Setters
}
And finally, check Spring boot logs - probably it is showing some kind of exception from Jackson, which will guide you on how to solve the mapping issue.

How to return JSON objects from spring boot controller methods?

I am using spring boot along with react js and postgresql. I am trying to print the rows of table from postgresql to a react js page. I have used crud repository function findAll() in the controller method to get the List. My problem is that when I am printing the List in spring boot console, it prints the list but it's printing empty objects' list when that url is accessed.
User.java
#Entity
#Table(name="users")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
public User() {
}
public User(String name, String email) {
this.name = name;
this.email = email;
}
#Override
public String toString() {
return String.format("User[id=%d, name='%s', email='%s']",this.id,this.name,this.email);
}
}
UserRepository.java
public interface UserRepository extends CrudRepository<User, Long>{
}
WebController.java
public class WebController {
#Autowired
private UserRepository repository;
#GetMapping("home")
public String home() {
System.out.println("whaaat");
return "hi ssup";
}
#GetMapping("/save")
public String process() {
repository.save(new User("vidhi","vd#gmail.com"));
System.out.print("apple ");
return "Done";
}
#GetMapping("findall")
#ResponseBody
public Collection<User> findAll() {
System.out.println("cc");
List<User> users = (List<User>) repository.findAll();
System.out.println(users);
return users;
}
}
On printing users in boot: [User[id=33, name='i', email='vd#gmail.com'], User[id=34, name='v', email='d#gmail.com']
on localhost:8080/findall: [{},{}]
What's going on wrong here? I am very confused and trying to figure this out since a lot of time and it's eating my head.
Any help would be wonderful!
Thanks for your time.
You have to add getters and setters to the User class.
Change it to:
#GetMapping("findall", produces= MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<Collection<User>> findAll() {
System.out.println("cc");
List<User> users = (List<User>) repository.findAll();
System.out.println(users);
return ResponseEntity.ok(users);
}
change your repo to:
#Repository
public interface UserRepository extends JpaRepository<User, Long>{
}

Solr 7 with Spring data and basic authentication not working

#SpringBootApplication
public class SpringDataSolarApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDataSolarApplication.class, args);
}
#Bean
SolrTemplate solrTemplate() {
return new SolrTemplate(solrClientFactory());
}
#Bean
SolrClientFactory solrClientFactory() {
Credentials credentials = new UsernamePasswordCredentials("solr", "SolrRocks");
return new HttpSolrClientFactory(solrClient(), credentials , "BASIC");
}
#Bean
SolrClient solrClient() {
return new HttpSolrClient.Builder("http://localhost:8983/solr").build();
}
}
public interface EmployeeRepository extends SolrCrudRepository{
Employee findByName(String name);
}
#RestController
public class EmployeeController {
#Autowired
private EmployeeRepository repository;
#PostConstruct
public void addEmployees() {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("373", "Basant", new String[] { "Bangalore", "BTM" }));
employees.add(new Employee("908", "Santosh", new String[] { "Hyderbad", "XYZ" }));
employees.add(new Employee("321", "Sagar", new String[] { "Pune", "PQR" }));
repository.saveAll(employees);
}
#GetMapping("/getALL")
public Iterable<Employee> getEmployees() {
return repository.findAll();
}
#GetMapping("/getEmployee/{name}")
public Employee getEmployeeByName(#PathVariable String name) {
return repository.findByName(name);
}
}
the getALL operation is working fine but the save operation failed with this error. Please help
Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:225) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.7.jar:4.5.7]
... 63 common frames omitted
Came across same issue and solved with extending HttpSolrClient and applying same backend approach with recommended way mentioned on Solr docs but getting credentials from constructor not setting on each request.
class CustomSolrClient extends HttpSolrClient {
#Nullable
private final String username;
#Nullable
private final String password;
CustomSolrClient(Builder builder, String username, String password) {
super(builder);
this.username = username;
this.password = password;
}
#Override
public NamedList<Object> request(SolrRequest request, ResponseParser processor, String collection) throws SolrServerException, IOException {
HttpRequestBase method = createMethod(request, collection);
if (username != null && password != null) {
String userPass = username + ":" + password;
String encoded = Base64.byteArrayToBase64(userPass.getBytes(UTF_8));
method.setHeader(new BasicHeader("Authorization", "Basic " + encoded));
}
return executeMethod(method, processor, request instanceof V2Request || request.getPath().contains("/____v2"));
}
}
And create bean using that:
#Bean
public SolrClient solrClient() {
return new CustomSolrClient(new HttpSolrClient.Builder(properties.getHost()), properties.getUsername(), properties.getPassword());
}
This may seem as an ugly approach but if you check HttpSolrClientFactory sources it's even more uglier which actually accesses private field of HttpClient belongs to Solr client.

Getting AssertionError while using ObjectifyService.register

I am in the middle of trying to refactor some of my data models, but I've run into a problem that I don't understand.
Originally I had a simple data model comprised of 3 entity classes, which looked something like this:
#Entity
public final class Teacher {
#Id
private Long id;
private String primarySubject;
public Teacher() {}
public Teacher(String primarySubject) {
this.primarySubject = primarySubject;
}
//getters & setters
}
#Entity
public final class Student {
#Id
private String username;
#Load
#Index
private Ref<Teacher> homeRoomTeacher;
public Student() {}
public Student(String username, Teacher teacher) {
this.username = username;
homeRoomTeacher = Ref.create(teacher);
}
//getters & setters
}
#Entity
public final class School {
#Id
private String name;
#Load
private Set<Ref<Teacher>> teachers;
#Load
private Set<Ref<Student>> students;
public School() {}
public School(String name) {
this.name = name;
}
//getters & setters
}
And this all worked fine.
But we decided that it would be more useful for us to embed the entities directly instead of Refs...
#Entity
#Embed
public final class Teacher {
#Id
private Long id;
private String primarySubject;
public Teacher() {}
public Teacher(String primarySubject) {
this.primarySubject = primarySubject;
}
//getters & setters
}
#Entity
#Embed
public final class Student {
#Id
private String username;
#Index
private Ref<Teacher> homeRoomTeacher;
public Student() {}
public Student(String username, Teacher teacher) {
this.username = username;
homeRoomTeacher = Ref.create(teacher);
}
//getters & setters
}
#Entity
public final class School {
#Id
private String name;
private Set<Teacher> teachers;
private Set<Student> students;
public School() {}
public School(String name) {
this.name = name;
}
//getters & setters
}
After making those changes, then all of our junit tests started to fail with an AssertionError during registration of the School class in our test setup methods which look like:
#Before
public void setUp() throws Exception {
helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
helper.setUp();
ObjectifyService.register(Teacher.class);
ObjectifyService.register(Student.class);
ObjectifyService.register(School.class);
// more setup
}
The AssertionError doesn't appear until the line that registers the School class, and according to the stack trace is being thrown from the method "com.googlecode.objectify.impl.translate.CreateContext.enterCollection" but I'm not certain how to go about fixing it.
Does anyone have any ideas?
I suspect the error you are getting is to do with the fact that you are trying to register a class which you have annotated with #Embed.
The objectify documentation clearly states that #Embed classes do not have to be registered - maybe this is the cause of the issue.
Also, I'm not 100% sure on this but I don't think you need #Id on an embedded class.
I would suggest you give the following changes a go:
#Embed
public final class Teacher {
#Id
private Long id;
private String primarySubject;
public Teacher() {}
public Teacher(String primarySubject) {
this.primarySubject = primarySubject;
}
//getters & setters
}
#Embed
public final class Student {
#Id
private String username;
#Index
private Ref<Teacher> homeRoomTeacher;
public Student() {}
public Student(String username, Teacher teacher) {
this.username = username;
homeRoomTeacher = Ref.create(teacher);
}
//getters & setters
}
#Before
public void setUp() throws Exception
{
helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
helper.setUp();
ObjectifyService.register(School.class);
// more setup
}
Hope this helps!

Access Arrays inside Java Objects

How do I obtain values of an array that is located inside a java object in a jsp page?
I have set an object attribute so that in the jsp page I can call the object like so
${obj.property}
My question is how would I obtain property String [] example from Object obj?
<c:forEach var="prop" items="${obj.example}">
<td>${prop}</td>
</c:forEach>
I get Errors that tell me the class obj.Obj does not have the property property 'example'
and obviously I don't get the data out.
Actual errors:
org.apache.jasper.JasperException: javax.el.PropertyNotFoundException: The class 'roommate.Roommate' does not have the property 'favProfessors'.
javax.el.PropertyNotFoundException: The class 'roommate.Roommate' does not have the property 'favProfessors'
And my actual class:
package roommate;
public class Roommate{
public String firstname;
public String lastname;
public String gender;
public String place;
public String[] favProfessors;
public Roommate(String fname, String lname, String roommateGender, String hangout,String[] professors) {
firstname= fname;
lastname= lname;
gender= roommateGender;
place= hangout;
favProfessors= professors;
}
public String getFirstname()
{
return firstname;
}
public void setFirstname(String newFirstname)
{
this.firstname = newFirstname;
}
public String getLastname()
{
return lastname;
}
public void setLastname(String newLastname)
{
this.lastname = newLastname;
}
public String getGender()
{
return gender;
}
public void setGender(String newGender)
{
this.gender = newGender;
}
public String getHangout()
{
return place;
}
public void setHangout(String newPlace)
{
this.place = newPlace;
}
public String[] getProfessors()
{
return favProfessors;
}
public void setProfessors(final String[] newfavProfessors)
{
this.favProfessors = newfavProfessors;
}
public void addRoommate(String fname, String lname, String roommateGender, String hangout,String[] professors)
{
}
}
I create the object in my servlet as well ass the Atrribute
String [] profArray = request.getParameterValues("professor");
Roommate roommate= new Roommate(
session.getAttribute("fname").toString(),
session.getAttribute("lname").toString(),
session.getAttribute("gender").toString(),
session.getAttribute("hangout").toString(),
profArray);
session.setAttribute("roommate",roommate);
I asked this earlier but did not receive a clear answer. I think my issue is in pulling the data out in the jsp alone in my forEach that I mentioned at the top
javax.el.PropertyNotFoundException: The class 'roommate.Roommate' does not have the property 'favProfessors'
Java is right. You do not have a getFavProfessors() method in that class. It's instead the following:
public String[] getProfessors()
{
return favProfessors;
}
You have 2 options: use ${roommate.professors} instead, or fix the getter method name to be getFavProfessors().
In contrary to what most starters think, EL does not access private properties directly. EL just calls the public getter/setter methods according the Javabeans specification. The real private property behind it can have a completely different name or even not exist at all.

Resources