I made a service which has saving function:
ClientService.java
@Transactional
public ClientDTO signUp(ClientSignupDTO clientSignupDTO) {
Client client = Client.builder()
.clientID(clientSignupDTO.getClientID())
.clientPassword(passwordEncoder.encode(clientSignupDTO.getClientPassword()))
.clientNickname(clientSignupDTO.getClientNickname())
.clientActivated(true)
.build();
client = clientRepository.save(client);
clientAuthorityRepository.save(new ClientAuthority(client, authorityRepository.getById("ROLE_CLIENT")));
client = clientRepository.findOneWithAuthoritiesByClientID(client.getClientID()).orElseThrow(() -> new IllegalStateException("Client does not exist"));
log.debug("{}", client.getAuthorities()); //This line throws NullPointerException
return new ClientDTO(client);
}
I saved Client
entity and ClientAuthority
entity with saved Client
's ID for M:N mapping.
But when I try to find Client
in same function, JPA returns Client
without ClientAuthority
.
Client.java
@Entity
@Table(name = "client")
@Getter
@Setter
@Builder
@NoArgsConstructor
public class Client {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "client_id", length = 50)
private String clientID;
@Column(name = "client_password")
private String clientPassword;
@Column(name = "client_nickname", length = 50)
private String clientNickname;
@Column(name = "client_since", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Date clientSince;
@Column(name = "client_activated")
private boolean clientActivated;
@JsonIgnore
@OneToMany(mappedBy = "client")
private Set<ClientAuthority> clientAuthorities;
@JsonProperty("authorities")
public Set<Authority> getAuthorities() {
return clientAuthorities.stream().map(ClientAuthority::getAuthority).collect(Collectors.toSet());
}
public Client(Long id, String clientID, String clientPassword, String clientNickname, Date clientSince, boolean clientActivated, Set<ClientAuthority> clientAuthorities) {
this.id = id;
this.clientID = clientID;
this.clientPassword = clientPassword;
this.clientNickname = clientNickname;
this.clientSince = clientSince;
this.clientActivated = clientActivated;
this.clientAuthorities = clientAuthorities;
}
}
ClientAuthority.java
@Entity
@Table(name = "client_authority")
@Getter
@Setter
@Builder
@NoArgsConstructor
public class ClientAuthority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "client_authority_id")
private Long clientAuthorityID;
@ManyToOne
@JoinColumn(name = "client_id")
private Client client;
@ManyToOne
@JoinColumn(name = "authority_name")
private Authority authority;
public ClientAuthority(Long clientAuthorityID, Client client, Authority authority) {
this.clientAuthorityID = clientAuthorityID;
this.client = client;
this.authority = authority;
}
public ClientAuthority(Client client, Authority authority) {
this.client = client;
this.authority = authority;
}
}
Repository that I used to find client is Spring Data JPA repository.
ClientRepository.java
@Repository
public interface ClientRepository extends JpaRepository<Client, Long> {
Optional<Client> findOneWithAuthoritiesByClientID(String clientID);
}
Since clientAuthorities
inside Client
that returned by findOneWithAuthoritiesByClientID
is null, Client.getAuthorities
returns NullPointerException
.
Other properties such as clientID
, clientNickname
, etc. works fine but only clientAuthorities
is null.
How can I get Client
with Set<ClientAuthority>
after save them?
Thanks.
Edited all save
into saveAndFlush
in function signUp
. But it keeps throwing NullPointerException
.
@Transactional
public ClientDTO signUp(ClientSignupDTO clientSignupDTO) {
Client client = clientRepository.saveAndFlush(Client.builder()
.clientID(clientSignupDTO.getClientID())
.clientPassword(passwordEncoder.encode(clientSignupDTO.getClientPassword()))
.clientNickname(clientSignupDTO.getClientNickname())
.clientActivated(true)
.build());
log.debug("{}, {}, {}, {}", client.getId(), client.getClientID(), client.getClientNickname(), client.getClientSince());
clientAuthorityRepository.saveAndFlush(new ClientAuthority(client, authorityRepository.getById("ROLE_CLIENT")));
client = clientRepository.findOneWithAuthoritiesByClientID(client.getClientID()).orElseThrow(() -> new IllegalStateException("Client does not exist"));
log.debug("{}, {}, {}, {}", client.getClientID(), client.getClientNickname(), client.getClientSince(), client.getAuthorities());
return new ClientDTO(client);
}
The log is:
Hibernate: insert into client (client_activated, client_id, client_nickname, client_password) values (?, ?, ?, ?)
2022-02-25 14:22:07.986 DEBUG 16684 --- [nio-8080-exec-3] c.d.s.service.ClientService : 4, test, test, null
Hibernate: insert into client_authority (authority_name, client_id) values (?, ?)
Hibernate: select client0_.id as id1_1_, client0_.client_activated as client_a2_1_, client0_.client_id as client_i3_1_, client0_.client_nickname as client_n4_1_, client0_.client_password as client_p5_1_, client0_.client_since as client_s6_1_ from client client0_ where client0_.client_id=?
2022-02-25 14:22:08.071 ERROR 16684 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at com.devjaewoo.springtest.entity.Client.getAuthorities(Client.java:46) ~[classes/:na]
When I test findOneWithAuthoritiesByClientID
function with sample data (with data.sql file) outside of signUp
function, It works fine.
Why doesn't it work properly only inside of signUp
function?
you may need to saveAndFlush
but I would recommend
final var client = clientRepository
.saveAndFlush(Client
.builder()
.clientID(clientSignupDTO.getClientID())
...
.build());
So you immediately get the managed copy.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.