I would be pleased if I could get my models sub collection into a combobox containing the values of said sub collection. The application I'm making is a hybrid of JavaFX and Spring. I used JavaFX for GUI and Spring Data JPA to interact with my database, which, elsewhere is being worked by a Spring Boot REST API. The models I'm using in my GUI app are copies of the models used in the REST API elsewhere.
Here's the models.
@Entity
@NoArgsConstructor
@Getter
@Setter
@Table(name = "users")
public class User implements Serializable {
private static final long serialVersionUID = 65981149772133526L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "USER_ID")
private Long id;
@Column(name = "PROVIDER_USER_ID")
private String providerUserId;
@Column(name = "enabled", columnDefinition = "BIT", length = 1)
private boolean enabled;
@Column(name = "DISPLAY_NAME")
private String displayName;
@Column(name = "created_date", nullable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
protected Date createdDate;
@Temporal(TemporalType.TIMESTAMP)
protected Date modifiedDate;
private String fullName;
private String phone;
private String company;
private String provider;
private String username;
private String formEmail;
@NotBlank
@Size(max = 50)
@Email
private String email;
@NotBlank
@Size(max = 120)
private String password;
@JsonIgnore
@ManyToMany
@JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") })
private Set<Role> roles;
public User(String username, String email, String pass) {
this.username = username;
this.email = email;
this.password = pass;
}
}
Here's the Role model.
package com.example.javafx;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.*;
import com.example.javafx.Role;
import com.example.javafx.User;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
public static final String USER = "USER";
public static final String ROLE_USER = "ROLE_USER";
public static final String ROLE_ADMIN = "ROLE_ADMIN";
public static final String ROLE_MODERATOR = "ROLE_MODERATOR";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ROLE_ID")
private Long roleId;
@Column(name = "USER_ID")
private String name;
// bi-directional many-to-many association to User
@ManyToMany(mappedBy = "roles")
private Set<User> users;
public Role(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Role role = (Role) obj;
if (!role.equals(role.name)) {
return false;
}
return true;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("Role [name=").append(name).append("]").append("[id=").append(roleId).append("]");
return builder.toString();
}
}
ERole enum
public enum ERole {
ROLE_USER,
ROLE_MODERATOR,
ROLE_ADMIN
}
The repo.
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
Boolean existsByUsername(String username);
Boolean existsByEmail(String email);
User findByEmail(String email);
}
@Component
public class SimpleUiController {
@Autowired
private UserRepository userRepo;
@FXML
private TableView<User> users_table;
@FXML
private TableColumn user_id_col;
@FXML
private TableColumn<User, Set<Role>> user_roles_col;
public void syncUsersTableWithDB() {
List<User> userFromServer = userRepo.findAll();
users = FXCollections.observableArrayList(userFromServer);
user_id_col.setCellValueFactory(new PropertyValueFactory("id"));
user_email_col.setCellValueFactory(new PropertyValueFactory("email"));
password_hash_col.setCellValueFactory(new PropertyValueFactory("password"));
user_fullname_col.setCellValueFactory(new PropertyValueFactory("fullName"));
user_formEmail_col.setCellValueFactory(new PropertyValueFactory("formEmail"));
user_phone_col.setCellValueFactory(new PropertyValueFactory("phone"));
user_company_col.setCellValueFactory(new PropertyValueFactory("company"));
//user_roles_col.
user_enabled_col.setCellValueFactory(new PropertyValueFactory("enabled"));
user_created_col.setCellValueFactory(new PropertyValueFactory("createdDate"));
user_modified_col.setCellValueFactory(new PropertyValueFactory("modifiedDate"));
users_table.setItems(users);
}
}
You'll see there is a user_roles_col access in the syncUsersTableWithDB function. I had other attempts but I'm not confident in my approach.
I tried setting a PropertyValueFactory like the others, then trying to modify the Set into strings of roles but was unable. So what I want to do is turn the Set into strings of the role string in a Combobox in a TableView. I hope I have explained it well, let me know if I need to explain further.