user15157252
user15157252

Reputation:

JPA keeps setting attributes as null

I am doing something stupid, but I cannot figure out what exactly. So I have an object User, which holds an automatic user and password creator. But in the creation, this is automatically set based on user input information. user+name, so the user can reset himself afterwards.

So when a user is added, the name and last name should create the user and pass. But my test keeps setting it as null.

JPA should be able to load this in a certain way. Without having to use any @post.. method. The user and pass have to be set with each creation of an object, but they cannot be inputted when someone creates the user. --> if I add the two in the constructor, and make a form that doesn't hold any field to fill up username and password (though using all the other ones), will it work with the protected constructor?


@Entity
@Table(name = "gebruikers")
@NamedEntityGraph(name = "Gebruiker.metConsigatiebonSet",
        attributeNodes = @NamedAttributeNode("consignatiebonSet"))
public class Gebruiker {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long idgebruikers;
    private String voornaam;
    private String naam;
    private String mail;
    private boolean mailOk;
    private String gebruikersnaam;
    private String pass;
    private String telefoonNr;
    private String straat;
    private String huisnummer;
    private String postcode;
    private String gemeente;
    @Enumerated(EnumType.STRING)
    private Gebruikersrol rol;
    private String extraOpmerking;
    @OneToMany @JoinColumn(name = "consignatiebonId")
    //@OrderBy(attribute1, attribute2,..
    private Set<Consignatiebon> consignatiebonSet;

    public Gebruiker(String voornaam, String naam, String mail, boolean mailOk,
                     String telefoonNr, String straat, String huisnummer, String postcode, String gemeente,
                     Gebruikersrol rol, String extraOpmerking) {
        this.voornaam = voornaam;
        this.naam = naam;
        this.mail = mail;
        this.mailOk = mailOk;

        //the two below keep getting set as null
        this.gebruikersnaam = makeUser(naam, voornaam);
        makePass(naam, voornaam);

        this.telefoonNr = telefoonNr;
        this.straat = straat;
        this.huisnummer = huisnummer;
        this.postcode = postcode;
        this.gemeente = gemeente;
        this.rol = rol;
        this.extraOpmerking = extraOpmerking;
        this.consignatiebonSet = new LinkedHashSet<>();
    }

    protected Gebruiker() {};
    
    /*logic to determine input*/
    public String makeUser(String naam, String voornaam) {
        var gebruiker = new StringBuilder(naam);
        gebruiker.append(".").append(voornaam);
        return String.valueOf(gebruiker);
    }
    
    public void makePass(String naam, String voornaam) {
        var pass = naam + voornaam;
        this.pass = pass;
    }

    /*getters*/

    public long getIdgebruikers() {
        return idgebruikers;
    }

    public String getVoornaam() {
        return voornaam;
    }

    public String getNaam() {
        return naam;
    }

    public String getMail() {
        return mail;
    }

    public boolean isMailOk() {
        return mailOk;
    }

    public String getGebruikersnaam() {
        return gebruikersnaam;
    }

    public String getPass() {
        return pass;
    }

    public String getTelefoonNr() {
        return telefoonNr;
    }

    public String getStraat() {
        return straat;
    }

    public String gethuisnummer() {
        return huisnummer;
    }

    public String getPostcode() {
        return postcode;
    }

    public String getGemeente() {
        return gemeente;
    }

    public Gebruikersrol getRol() {
        return rol;
    }

    public String getExtraOpmerking() {
        return extraOpmerking;
    }


    /*mogelijkheid om consignatiebonnen in te voegen*/
    public Set<Consignatiebon> getConsignatiebonSet() {
        return Collections.unmodifiableSet(consignatiebonSet);
    }

    public boolean add(Consignatiebon bon) {
        if (bon == null) {
            throw new NullPointerException();
        }
        return consignatiebonSet.add(bon);
    }

}

Upvotes: 0

Views: 1131

Answers (3)

user15157252
user15157252

Reputation:

Answer:JPA cannot use logic to correct db input in the entity itself. I should have put this logic in my service or my frontend application. Determing values based on db-values can be set in entity, but it cannot be placed in the db-value. for instance, I could have set a getter:

getUsername() {
return name + "." + firstname;
}

but this would not set a username in de db.

Jpa entities specify the table/entity, it does't determine how the object gets created.

Upvotes: 0

mithildobarkar
mithildobarkar

Reputation: 51

The application is trying to invoke below two methods from the parameterized constructor. JPA will invoke no-args constructor for creating objects, due to which you are getting null value.

this.gebruikersnaam = makeUser(naam, voornaam);
makePass(naam, voornaam);

Calling them through no-args, could resolve the issue.

Upvotes: 0

Jens Schauder
Jens Schauder

Reputation: 82008

The logic for presetting these values is in your constructor, but you are loading the entities using JPA (via Spring Data JPA). But JPA uses your the parameterless constructor, therefore the code in question never gets executed.

You can put the logic for presetting this values in a life cycle method on the entity like the following:

@PostLoad
public void initDefaults() {
    this.gebruikersnaam = makeUser(naam, voornaam);
    makePass(naam, voornaam);
}

For more information about JPA events see: https://www.baeldung.com/jpa-entity-lifecycle-events

Note that you probably want to add a check if the values are already set, so you don't overwrite them.

Upvotes: 1

Related Questions