user2569072
user2569072

Reputation:

How to use CDI and Dependency Injection

I want to use the same object "User" within the Farma and the Pata objects. The object user is first initialized inside the Farma object. I tried to annotated with @inject, but the object user inside Pata, has the name with null value. Please, can anyone help me understand what I am doing wrong? Thank!

@Named
@SessionScoped
public class Farma implements Serializable {
    @Inject private User user;

    @PostConstruct
    public void initialize(){
         user.setName("MyName");
    }
    // Getters and Setters
}

@Named
@SessionScoped
public class Pata implements Serializable {
    @Inject private  User user;

    public String getFuzzyName() {
        // Here I want to use the object "user" with the name "MyName" to do some logic
    }
    // Getters and Setters
}

public class User implements Serializable {
    private String name;

    // Getters and Setters

Upvotes: 0

Views: 485

Answers (3)

Matthias H
Matthias H

Reputation: 1310

As axiopisty said, adding @Named @SessionScoped is the correct way.

I tried and it works great.

@Named
@SessionScoped
public class Pata implements Serializable {
    @Inject
    private User user;

    public String getFuzzyName() {
        System.out.println(user.getName());
        return user.getName();
    }

    public User getUser() {
        return user;
    }

    public void setUser(final User user) {
        this.user = user;
    }
}

@Named
@SessionScoped
public class Farma implements Serializable {
    @Inject
    private User user;

    @PostConstruct
    public void initialize() {
        user.setName("MyName");
    }

    // Getters and Setters

    public User getUser() {
        return user;
    }

    public void setUser(final User user) {
        this.user = user;
    }
}


@Named
@SessionScoped
public class User implements Serializable {
    private String name = "Default";

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}


<h:outputText value="#{farma}"></h:outputText><br />
<h:outputText value="#{pata}"></h:outputText><br />
<h:outputText value="#{pata.fuzzyName}"></h:outputText>

Upvotes: 0

Yuri
Yuri

Reputation: 1765

Just scoping a User object won't allow you to initialize it. Use "producer method" to control bean's creation. Try this:

@SessionScoped
public class Pata implements Serializable {
    @Inject
    @SessionUser // inject here using the producer method
    private  User user;

    public String getFuzzyName() {
        return user.getName();
    }
}
@SessionScoped
public class Farma implements Serializable {
    @Produces
    @SessionUser    // qualifier to tie injection points to this method
    @SessionScoped  // to ensure it will be called once per session for any number of injection points
    public User produceUser() {
        System.out.println("Creating user");
        User u = new User();
        u.setName("User");
        return u;
    }
}
////// that's your custom qualifier, it's in a separate file
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SessionUser {}

// no scopes here, it is defined by the producer method
public class User implements Serializable {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

Upvotes: 1

axiopisty
axiopisty

Reputation: 5146

You need to understand scoping of CDI beans. The default scope, if none is specified, is the @Dependent scope, which means that an object exists to serve exactly one client (bean) and has the same lifecycle as that client (bean).

In this case it means that the user in Farma only exists for the Farma class and lives for the life of the Farma class.

The user in Pata is a different instance, and its lifecycle matches that of Pata.

You need to properly scope the User object.

Upvotes: 0

Related Questions