Search code examples
jsfjsf-2primefacespropertiessuperclass

JSF access private/protected property of a super class


I am very new to JSF and this is the first project I work on (got a bit too lazy with jsp) so please forgive me if the question is trivial. So I have a Super Class Device

@Entity
@Table(name = "Devices")
public class Device
{
    protected bool Authorized

    public bool isAuthorized()
      { return this.Authorized;}
    public void setAuthorized(bool Authorized)
      { this.Authorized = Authorized;}
}

and a sub class SensorDevice that extends the Super Class Device

public class SensorDevice extends Device
{
  // has its own properties which dont matter
}

and a Managed Bean UIDeviceManager

@ManagedBean(name = "DeviceManager")
@SessionScoped
public class UIDeviceManager 
{
   private List<SensorDevice> Pending;
   // in constructor, Pending List gets populated with the devices requiring Authorization
}

and an xhtml page which contains a Table for the Pending Devices

<p:dataTable var="device" value="#{DeviceManager.pending}">
<p:column headerText="Device Authorization">
<h:form>
<p:inputSwitch 
    value="#{device.isAuthorized()}" 
    binding="#{AuthorizationInputSwitch}" 
    offLabel="UnAuthorized" 
    onLabel="Authorized">    
<p:ajax 
    event="change" 
    listener="#{device.setAuthorized(AuthorizationInputSwitch.value)}" />
</p:inputSwitch>   
</h:form>               
</p:column>

Now unless the syntax in the xhtml is completely messed up (I tried my best there and would appreciate guidance), the function setAuthorized for that particular device instance should be called (even with the wrong input, but will sort that later by modifying the setter function), but that doesnt happen, the Ajax doesnt get called. Instead, the inputSwitch tries to update its "value property source" and attempts to look for a property isAuthorized() in the class SensorDevice which it fails to find.

Now I am aware that this could be easily solved by making the Boolean Authorized public in the super class but as you can see it is also a JPA entity that is persisted in a database to keep track of the devices, so the only option is to keep it protected.

So how do I update parameters of a Super class from a sub-class instance in a Managed Bean from a public function rather than direct access to the parameter itself (I thought JSF looked for the setters and getters but whatever)

Btw value="#{device.isAuthorized()}"works correctly but if I try the property directly it fails ( I guess its obvious at this point )

One last thing, if the approach/architecture is wrong, please advise on what is the correct layout to achieve this functionality. I am sure there is a standard way to integrate JSF and JPA without duplicating entities and wrappers


Solution

  • I think you must use field name in value attribute of InputSwitch component like this:

    <p:inputSwitch 
        value="#{device.authorized}" 
        binding="#{AuthorizationInputSwitch}" 
        offLabel="UnAuthorized" 
        onLabel="Authorized"> 
    

    Instead of:

    <p:inputSwitch 
        value="#{device.isAuthorized()}" 
        binding="#{AuthorizationInputSwitch}" 
        offLabel="UnAuthorized" 
        onLabel="Authorized">    
    

    JSF will use isAuthorized and setAuthorized method (uses Java Beans standard convention to recognize getter and setter methods)

    So i think you don't need the ajax part to call setter method.