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);
}
}
CodePudding user response:
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.
CodePudding user response:
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.