How to fix unsatisfied dependencies for injecting Models (javax.mvc.Models)? - java

I get this error while following this tutorial for mvc 1.0.
[ERROR] Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Models with qualifiers #Default at injection point [BackedAnnotatedField] #Inject ch.xxx.controller.UserController.models at ch.xxx.controller.UserController.models(UserController.java:0)
I tried...
putting my beans.xml into multiple places (resources/META-INF/beans.xml | webapp/WEB-INF/beans.xml)
changing the bean-discovery-mode to "all"
annotated my User.class with #Named and/or #SessionScoped (not in tutorial)
This is my User.class
#Entity
#Table(name = "users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String email;
private String password;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Here my UserForm.class
import javax.ws.rs.FormParam;
public class UserForm {
#FormParam("id")
private String id;
#FormParam("email")
private String email;
#FormParam("password")
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
and at last my UserController.class, where the error actually happens:
#Controller
#Stateless
#Path("/user")
public class UserController {
#PersistenceContext
EntityManager entityManager;
#Inject
Models models;
#GET
#View("user/all-users.html")
public void getAllREST(){
List<User> allUsers = entityManager.createNamedQuery("User.findAll", User.class).getResultList();
models.put("users", allUsers);
}
#GET
#Path("/create")
public String getCreateRESTForm(){
return "user/create-user.html";
}
#POST
#Path("/create")
public String create(#BeanParam UserForm userForm){
User user = new User();
user.setEmail(userForm.getEmail());
user.setPassword(user.getPassword());
entityManager.persist(user);
return "redirect:/user";
}
}
I'm really lost here, since I have no idea what more to change and what the actual problem is for such a simple form. And don't mind the plain text password, it's just for testing.

I have not worked with JEE MVC yet but this seems to be CDI related issue and should not be located in the MVC framework, because it should only make use of CDI.
The reason for this exception, as already answered, is because the CDI Container does not find any injectible implementations of this interface, and therefore cannot inject it.
Take a look at the javadoc which says, that any implementation of this interface needs to be injectible and request scoped. Are you sure that the implementing bean you expect fulfills these requirements?
https://github.com/javaee/mvc-spec/blob/master/api/src/main/java/javax/mvc/Models.java
Is there a beans.xml present in the artifact the bean resides?
src/main/reosurces/META-INF/beans.xml (for JAR)
src/main/webapp/WEB-INF/beans.xml (for WAR)
Is the implementing bean annotated with #RequestScoped?
If referenced via EL, is the bean annotated with #Named?
Another thing is, do not make JPA entities CDI-Beans and make them injectible, this is a bad approach and the Models interfaces and its implementations should not require it.

Related

rest api return duplicate values in postman and spring boot h2

I am new spring boot developer and i am trying to develope and rest api . when I do it ,I get and issues that my api return two duplicated response in postman .But i haven't code anythiong to get duplicated valuese in my code . the one of duplicate values is my model clase variable and athor one is table's attribute name .
below response in postman
model class
public class person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY )
private Long id;
#Column(name = "name")
private String Name ;
#Column(name ="surname")
private String Surname;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getSurname() {
return Surname;
}
public void setSurname(String surname) {
Surname = surname;
}
}
repository
#Repository
public interface personRepository extends JpaRepository<person,Long> {
}
controller
#RestController
#RequestMapping("/person")
public class personController {
#Autowired
private personRepository repository;
public personController(personRepository repository) {
this.repository = repository;
}
#GetMapping("/view/list/person")
private List<person> viewperson() {
return repository.findAll();
}
#PostMapping("/insert/person")
private person savePerson(#RequestBody person obj) {
return repository.save(obj);
}
#DeleteMapping("/delete/{id}")
private void delete(#PathVariable Long id) {
repository.deleteById(id);
}
}
application.properties
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialec
t
The problem is that you're not following the proper conventions in your naming strategy.
Due to this, Jackson doesn't know that your getters (getSurname(), getName()) are referencing the fields Surname and Name. That's why it serializes both your fields and your getters separately to JSON.
To fix this, you can follow the Java naming conventions and use a lowercase letter for the first character of your fields.
For example:
#Column(name = "name")
private String name; // Change this
#Column(name ="surname")
private String surname; // Change this
This will change your JSON output to:
{
"id": 1,
"name": "bryan",
"surname": "Nicky"
}
If you want to keep your JSON with capital letters, you can use the #JsonProperty annotation:
#JsonProperty("Name") // Add this
#Column(name = "name")
private String name;
#JsonProperty("Surname") // Add this
#Column(name ="surname")
private String surname;
Unrelated to your question, but according to those naming conventions, your classes should start with a capital (eg. Person, PersonController, PersonRepository, ...).

Room #Query error: Cannot find method parameters

in my project I have a library module and an application module using it. In both modules I have the same gradle dependencies on Android Architecture Components library:
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:1.0.0"
implementation "android.arch.lifecycle:common-java8:1.0.0"
// Room
implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
In my library module I have defined a User entity
#Entity(tableName = "users",
indices = {#Index(value = {"firstName", "lastName"})})
public class User {
public enum ROLE {
...
}
public enum FEEDBACK_LEVEL {
...
}
#PrimaryKey
public int id;
#TypeConverters(UserConverters.class)
ROLE role;
#TypeConverters(UserConverters.class)
FEEDBACK_LEVEL feedbackLevel;
public String firstName;
public String lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public ROLE getRole() {
return role;
}
public void setRole(ROLE role) {
this.role = role;
}
public FEEDBACK_LEVEL getFeedbackLevel() {
return feedbackLevel;
}
public void setFeedbackLevel(FEEDBACK_LEVEL feedbackLevel) {
this.feedbackLevel = feedbackLevel;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
and the related DAO interface
#Dao
public interface UserDAO {
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertUser(User ... u);
#Query("select * from users where users.id = :userId")
LiveData<User> getUser(int userId);
}
In my application module I've created my database in which I'm using the entity defined in the library project
#Database(entities = {User.class}, version = 1)
public abstract class TDatabase extends RoomDatabase{
private static TDatabase sInstance;
public static TDatabase getInstance(final Context c) {
if(sInstance == null)
sInstance = Room.databaseBuilder(c, TDatabase.class, "t_db").build();
return sInstance;
}
public abstract UserDAO userDao();
}
The problem is that when I try to refer to a method parameter in a #Querystatement using its name I get the following error
Error:Each bind variable in the query must have a matching method parameter. Cannot find method parameters for :userId.
If I change the #Query from
#Query("select * from users where users.id = :userId")
LiveData<User> getUser(int userId);
to
#Query("select * from users where users.id = :arg0")
LiveData<User> getUser(int userId);
everything works fine.
Am I doing some mistakes? Why I'm getting this error?
I've googled for a solution but I found only results referring to Kotlin while I'm using Java.
This issue reported at https://issuetracker.google.com/issues/68118746 and fixed in version 1.1.0-alpha3, but only for Kotlin code since parameter names are always stored in Kotlin classes metadata.
For Java, there is only workaround with :arg0 until annotation like NamedArg will be added to Room.
I think you should use it like that:
#Query("select * from users where id = (:userId)")
LiveData<User> getUser(int userId);
This problem still pops up for me sometimes when working on db logic, but "Clean Project" usually fixes it in IntelliJ IDEA (should work just the same in Android Studio).

Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'userRepository'

I am having this error for several weeks now, and I do not know how to fix it. Similar solutions on Stack Overflow do not suit to my project.
I am currently using a mysql database, but encounter this problem whenever trying to start the server: StackTrace
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:run (default-cli) on project iPbackend: An exception occurred while running. null: InvocationTargetException: Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.resource.iPbackend.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)
I am using this mainController:
MainController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.resource.iPbackend.UserRepository;
import com.resource.iPbackend.User;
#Controller
#RequestMapping(path = "/main")
public class MainController {
#Autowired
private UserRepository userRepository;
#RequestMapping(path = "/reg", method = RequestMethod.POST)
public #ResponseBody String regNewUser (#RequestParam String firstName, #RequestParam String lastName, #RequestParam String email, #RequestParam String password, #RequestParam String username) {
User n = new User();
n.setFirstName(firstName);
n.setLastName(lastName);
n.setEmail(email);
n.setPassword(password);
n.setUsername(username);
userRepository.save(n);
return "User is stored in database: " + n;
}
#GetMapping(path = "/all")
public #ResponseBody Iterable<User> getAllUsers() {
return userRepository.findAll();
}
}
Together with this repository:
UserRepository.java
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.resource.iPbackend.User;
#Repository
public interface UserRepository extends CrudRepository<User, Long> {
}
And this Entity:
User.java
import org.springframework.data.annotation.Id;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String firstName;
private String lastName;
private String email;
private String password;
private String username;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
You need to include the annotation #EnableJpaRepositories in your base configuration class in order for Spring Data to register interfaces extending CrudRepository as spring beans.
Also the annotation #Repository does nothing on interfaces so this is not needed but it won't break anything by being there either.
EDIT:
You can also try and be more specific by telling the #EnableJpaRepositories annotation exactly where your repositories are. i.e.:
#EnableJpaRepositories("com.resource.iPbackened")
If you are using Springboot (#SpringBootApplication) then:
Try moving all your component classes in the same(or child) packages relative to your base Springboot config class.
For Instance:
I configured my SpringBoot base config class in package com.application
;
And I moved UserRepository(you mentioned) in package com.application.resource.iPbackend.User it worked for me without changing anything on the Annotation side. I got no error.
Since you havent shared the your Springboot Configuration so I am assuming you will be using defaults. If solution doesnt work, pl share your spring boot config which I can try on my side and respond.
Hope this helps!

How to enable auditing for MongoDB via Annotations in Spring

I wanted to enable some auditing features, such as #CreatedDate. I am not using Spring xml configuration file, so I cannot add mongo:auditing to Spring configuration. I was wondering if there was an alternative way of enable auditing. The following code is the model for user. But whenever I create a user, the date is not stored in the document, so the auditing it's not working. Could someone give me some help?
#Document(collection = "user")
public class User {
#Id
private String id;
#Indexed(unique = true)
private String email;
private String name;
#CreatedDate
private Date date;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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;
}
public String getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
Because you are not using configuration via XML, I believe you are using annotations. You own a class like this:
public class MongoConfig extends AbstractMongoConfiguration {...}
Thus, in addition to the annotations you should already have, add: #EnableMongoAuditing
Your configuration class will look like this now:
#Configuration
#EnableMongoRepositories(basePackages="...")
#EnableMongoAuditing
public class MongoConfig extends AbstractMongoConfiguration {...}
I hope this helps!
That's all you need. No subclasses or other stuff.
#Configuration
#EnableMongoAuditing
public class AnyConfig {}
You should write a configuration class in which you can connect to MongoDB database using mongoClient by passing db url. and add the anootaion of #EnableMongoAuditing on top of that class.

Models not being saved in Play Framework

Assume a model named User:
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
#Constraints.Required
public String password;
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
When I attempt to update an instance of User in my controller:
User user = User.find.where().eq("username", username).findUnique();
if(user != null) {
user.username = "some_new_username";
user.save();
}
no changes seem to be committed. I read somewhere that when you alter a model instance by its property, it does not get dirty and therefore no changes take place. Hence you should use a setter instead. In the documentation of Play Framework it is said that those setters (and getters) are generated automatically, but using user.setUsername(username) gives me a compilation error:
cannot find symbol [symbol: method setUsername(java.lang.String)] [location: class models.User]
Am I missing something?
Have you tried adding custom setters?
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
public void setUsername(String _username) {
username = _username;
}
#Constraints.Required
public String password;
public void setPassword(String _password) {
password = _password;
}
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
As far as I can tell, automatic getter/setter translation is broken in Play2. Your assignment:
user.username = "some_new_username";
should have triggered the function call:
user.setUsername("some_new_username");
This translation seems to be broken in Play 2. Here's my own question on the subject.

Categories

Resources