I am trying to take a value from one managed bean to another. I have a loginbean which gets the username and I need to take that value and put it into another managed bean sidebarbean. I am using JSF and thought i could go something like
#{sidebarbean.setUserName(loginbean.username)} but this does not work. Any suggestions?
Following your suggestion
#ManagedBean(name = "sidebarbean")
#SessionScoped
public class SideBarBean {
private ArrayList myContacts = new ArrayList();
private String user;
#PersistenceContext
private EntityManager em;
#Resource
private UserTransaction utx;
public SideBarBean() {
}
public ArrayList getMyContacts() {
myContacts.clear();
List<Contacts> list = em.createNamedQuery("Contacts.findByUsername")
.setParameter("username", user).getResultList();
for (Contacts c : list) {
myContacts.add(c.getContact());
}
return myContacts;
}
public void setMyContacts(ArrayList myContacts) {
this.myContacts = myContacts;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
#ManagedBean(name = "loginbean")
#SessionScoped
public class LoginBean {
#PersistenceContext
private EntityManager em;
#Resource
private UserTransaction utx;
#ManagedProperty(value="#{sidebarbean}")
private SideBarBean sbb;
private String username;
private String password;
private Boolean verified = false;
private Boolean authFail = false;
public LoginBean() {
}
public void update(){
sbb.setUser(username);
}
I get "Unable to create managed bean loginbean. The following problems were found: - Property sbb for managed bean loginbean does not exist. Check that appropriate getter and/or setter methods exist."
You can use #ManagedProperty annotation then you can access to same instance of SideBarBean.
#ManagedBean(name="loginbean")
public class LoginBean{
#ManagedProperty(value="#{sidebarbean}")
private SideBarBean sidebarbean;
public void update(){
sidebarbean.setUserName("xxxx");
}
}
Related
I have a class with two final fields of the same type, and I need to make second field injected with null if property props.enabled in application.yml is false. However, if it's false Spring Boot injects both fields with the same bean instance.
How to forbid Spring Boot injecting both fields of the same type with the same bean instance?
#AllArgsConstructor
public class MySettings {
private int val;
}
My configuration class
#Configuration
public class MySpringConfig {
#Bean
public MySettings settingsA() {
return new MySettings(1);
}
#Bean
#ConditionalOnProperty(prefix = "props", name = "enabled")
public MySettings settingsB() {
return new MySettings(2);
}
}
And this is my class
#Component
#RequiredArgsConstructor
public class MyClass {
private final MySettings settingsA; // MySettings(1)
private final MySettings settingsB; // also MySettings(1) but must be null if props.enabled=false
#Value("${props.enabled}")
private boolean enabled;
...
}
This is part of the real project, so I have very little space to deviate from
UPDATE
I came up with solution of constructor injection but the code starts to look ugly
#Component
public class MyClass {
private final MySettings settingsA;
private final MySettings settingsB;
private boolean enabled;
public MyClass(MySettings settingsA,
#Nullable #Qualifier("settingsB") MySettings settingsB,
#Value("${props.enabled}") boolean enabled) {
this.settingsA = settingsA;
this.settingsB = settingsB;
this.enabled = enabled;
}
...
You need a qualifier to tell Spring which bean to inject:
#Configuration
public class MySpringConfig {
#Bean(name = "SettingsA")
public MySettings settingsA() {
return new MySettings(1);
}
#Bean(name = "SettingsB")
#ConditionalOnProperty(prefix = "props", name = "enabled")
public MySettings settingsB() {
return new MySettings(2);
}
}
And now in MyClass:
#Component
public class MyClass {
private final MySettings settingsA;
private final MySettings settingsB;
#Value("${props.enabled}")
private boolean enabled;
public MyClass(#Qualifier("SettingsA") MySettings settingsA, #Qualifier("SettingsB") MySettings settingsB) {
this.settingsA = settingsA;
this.settingsB = settingsB;
}
...
}
However, since one of those Beans might not be available I believe you need to not include it in the constructor injection otherwise you will get an error. In that case you need to do the following:
#Component
public class MyClass {
#Qualifier("SettingsA")
#Autowired
private MySettings settingsA;
#Qualifier("SettingsB")
#Autowired(required = false)
private MySettings settingsB;
#Value("${props.enabled}")
private boolean enabled;
...
}
this is my configuration
#EnableTransactionManagement
#EnableScheduling
#EnableAutoConfiguration
#ComponentScan(basePackages = {"id.co.babe.neo4j.service"})
#Configuration
public class MyNeo4jConfiguration extends Neo4jConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(MyNeo4jConfiguration.class);
#Value("${neo4j.server.user}")
private String user;
#Value("${neo4j.server.pass}")
private String pass;
#Value("${neo4j.server.host}")
private String host;
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer(host,user,pass);
}
#Override
public SessionFactory getSessionFactory() {
return new SessionFactory("app.neo4j.domain");
}
#Bean
#Primary
public Neo4jOperations getNeo4jTemplate() throws Exception {
return new Neo4jTemplate(getSession());
}
and this is my domain User
#NodeEntity
public class User{
#GraphId
private Long Id;
private String name;
private int age;
private String country;
and my service interface
public interface UserService {
public User create(User user);
public User read(User user);
public List<User> readAll();
public User update(User user);
public Boolean delete(User user);
}
and my implementation
#Service
#Transactional
public class UserServiceImpl implements UserService{
#Autowired
Neo4jOperations template;
#Override
public User create(User user){
return template.save(user);
}
and this is my main class
for(int i = 0; i < 10; i++){
app.neo4j.domain.User user = new app.neo4j.domain.User();
user.setAge(13);
user.setCountry("Philly");
user.setId(i);
user.setName("Ibanez" + i);
LOGGER.info("Inserting {}",user.getName());
service.create(user);
}
no error was found, but when I go to neo4j console (localhost:7474), and run this query match(n) return n, which should return all nodes in the database. unfortunately there was no nodes found even though i was able to save without errors. I wonder what's wrong.
I also tried doing it with #enablingNeo4jRepositories with no difference to the result.
Your code should never set the value of the #GraphId field. This field is used internally to attach entities to the graph.
If you remove user.setId(i);, your entities should be saved correctly.
Note that you can add your own custom ID field, but you still need another field for the GraphID e.g.
#GraphId private Long graphId; //used internally, never assign a value
private Long id; //your application id, stored as a property on the entity
I have a simple project, based on this guide. I created a simple REST interface and I want it to use my database. I added Hibernate to the dependencies and created the DAO class. I'm using Spring Tool-Suite for IDE. As far as I understand I should add some beans to tell the classes what to use but I don't understand how. Here are my classes.
Application.java
package com.learnspring.projectfirst;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Marker.java
package com.learnspring.projectfirst;
#Entity
public class Marker {
#Id
#Column
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#Column
private double longitude;
#Column
private double latitude;
#Column
private String address;
public Marker() {
// Empty constructor
}
public Marker(long id, double longitude, double latitude, String address) {
this.id = id;
this.longitude = longitude;
this.latitude = latitude;
this.address = address;
}
//Getters and Setters
}
MarkerController.java
package com.learnspring.projectfirst.controller;
#Controller
public class MarkerController {
private Logger logger = Logger.getLogger(MarkerController.class.getName());
#Autowired
private MarkerServiceImplementation markerService;
#RequestMapping(value="/markers", method=RequestMethod.GET)
public #ResponseBody List<Marker> getMarkers(#RequestParam(value="city", defaultValue="") String city) {
return this.markerService.getAllMarkers();
}
#RequestMapping(value="/markers/new", method=RequestMethod.POST)
public #ResponseBody Marker addMarker(#RequestBody Marker marker) {
this.markerService.addMarker(marker);
return marker;
}
}
MarkerDaoImplementation.java
package com.learnspring.projectfirst.dao;
#Repository
public class MarkerDaoImplementation implements MarkerDaoInterface {
#Autowired
private SessionFactory sessionFactory;
#Override
public void addMarker(Marker marker) {
this.sessionFactory.getCurrentSession().save(marker);
}
#Override
public void deleteMarker(int markerId) {
this.sessionFactory.getCurrentSession().delete(this.getMarker(markerId));
}
#Override
public Marker getMarker(int markerId) {
return (Marker) this.sessionFactory.getCurrentSession().get(Marker.class, markerId);
}
#Override
public List<Marker> getAllMarkers() {
return this.sessionFactory.getCurrentSession().createQuery("from Marker").list();
}
}
MarkerServiceImplementation.java
package com.learnspring.projectfirst.service;
#Service
public class MarkerServiceImplementation implements MarkerServiceInterface {
#Autowired
private MarkerDaoImplementation markerDao;
#Transactional
public void addMarker(Marker marker) {
this.markerDao.addMarker(marker);
}
#Transactional
public void deleteMarker(int markerId) {
this.markerDao.deleteMarker(markerId);
}
#Transactional
public Marker getMarker(int markerId) {
return this.markerDao.getMarker(markerId);
}
#Transactional
public List<Marker> getAllMarkers() {
return this.markerDao.getAllMarkers();
}
}
And here is the file structure:
I understand that I should tell my program the database name and the columns using beans but I don't understand how. How can I link the java code to the beans? Sorry I pasted so much code, I just wanted to make sure you have everything needed. Thank you in advance!
This is the one you need: Spring Boot with MySQL
Refer this example : Spring MVC with JdbcTemplate Example
The annotations in your "Marker" class determine the MySQL table and column names (based on the class and class variable names). The tablename will be "marker", with the columns "id", "longitude", "latitude", "address".
You forgot the most important part in your code: your spring configuration. it determines how the SessionFactory instance will be initialized before being injected into your DAO class. Here you have to set an appropriate connection to the MySQL Server (e.g. via an JNDI Resource)
I have implemented my validation for list of custom class as mention in this post. For reference here my code looks like
class TopDtoForm {
#NotEmpty
private String topVar;
private List<DownDto> downVarList;
//getter and setter
}
class DownDto {
private Long id;
private String name;
//getter and setter
}
#Component
public class TopDtoFormValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return TopDtoForm.class.equals(clazz);
}
#Override
public void validate(Object target, Errors errors) {
TopDtoForm topDtoForm = (TopDtoForm) target;
for(int index=0; index<topDtoForm.getDownVarList().size(); index++) {
DownDto downDto = topDtoForm.getDownVarList().get(index);
if(downDto.getName().isEmpty()) {
errors.rejectValue("downVarList[" + index + "].name", "name.empty");
}
}
}
}
So even I send empty name binding result has 0 error. I tested with topVar and it is working fine. My question is do I have to do any other configuration to say use this validator?
Thanks
In Spring MVC just annotate in TopDtoForm your list with #Valid and add #NotEmpty to DownDto. Spring will validate it just fine:
class TopDtoForm {
#NotEmpty
private String topVar;
#Valid
private List<DownDto> downVarList;
//getter and setter
}
class DownDto {
private Long id;
#NotEmpty
private String name;
//getter and setter
}
Then in RequestMapping just:
#RequestMapping(value = "/submitForm.htm", method = RequestMethod.POST) public #ResponseBody String saveForm(#Valid #ModelAttribute("topDtoForm") TopDtoForm topDtoForm, BindingResult result) {}
Also consider switching from #NotEmpty to #NotBlank as is also checks for white characters (space, tabs etc.)
I'm trying to access an ArrayList<String> which is in a javax.enterprise.context.ApplicationScope bean from a javax.enterprise.context.RequestScoped bean. I need the AS bean to be initialized at deployment, so I'm using a #javax.ejb.Singleton #javax.ejb.Startup bean to initialize my AS bean. I can see the array being created, but when I go to access it from the RS bean, it is null. I have #PreDestroy in the AS bean which prints out the contents of the array. When #PreDestroy is called, the array is null. Do variables persist in AS beans?
#Named("simpleTest")
#ApplicationScoped
public class SimpleTest implements Serializable{
private static final long serialVersionUID = -9213673463118041881L;
private ArrayList<String> apps;
public void simpleTest() {
createApps();
debugApps();
}
public void createApps() {
apps = new ArrayList<String>();
apps.add("This is string 1");
apps.add("This is string 2");
}
public void debugApps() {
System.out.println("Beginning debug...");
for (String a : apps){
System.out.println(a);
}
}
#PreDestroy
public void ending() {
System.out.println("Hey there, I'm about to destroy the SimpleTest Bean...");
debugApps();
}
/* Getters and setters */
...
RS Bean:
#Named("aBean")
#RequestScoped
public class ABean implements Serializable{
private static final long serialVersionUID = -7213673465118041882L;
private ArrayList<String> myApps;
private String str;
#Inject
private SimpleTest st;
public void initStr(){
if (myApps != null){
for (String s : myApps){
setStr(s);
}
}
}
#PostConstruct
public void init(){
setMyApps(st.getApps());
initStr();
}
public String getErrs(){
String errs = "I couldn't find the apps";
if (myApps != null){
errs = "I found the apps!";
}
if (str != null){
errs = str;
}
return errs;
}
/* Getters and setters */
The only place you initialize your ArrayList<String> apps is in createApps method but this isn't called nor in class constructor nor in a #PostConstruct decorated method. Looks like you need to decorate simpleTest with #PostConstruct:
#PostConstruct
public void simpleTest() {
//...
}