need suggestion schema design for my web app - java

I have a quiz app in development under my belt, but I'm confused of getting schema design correct need help in this case please.
I've quiz, question, answer, and answerOptions Entities as following
quiz
#Entity
public class Quiz implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long quizId;
private String quizTitle;
#OneToMany(mappedBy = "quiz", fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
private Set<Question> questions = new HashSet<Question>();
#ManyToMany(mappedBy = "quizs", fetch = FetchType.EAGER, cascade = { CascadeType.REFRESH})
#JsonBackReference
private Set<History> histories = new HashSet<History>();
// omitting getters and setters
}
question
#Entity
public class Question implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long questionId;
private String questionText;
private Integer questionChoices;
private Integer questionNumbers;
#JsonIgnore
#ManyToOne
#JoinColumn(name = "quizId")
private Quiz quiz;
#OneToMany(mappedBy = "question", cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
private Set<Option> options = new HashSet<Option>();
#OneToOne(cascade = {CascadeType.REFRESH, CascadeType.PERSIST})
#JoinColumn(name = "answerId")
private Answer answer;
// omitting getters and setters
}
answerOptions
#Entity
#Table(name="answerOptions")
public class Option implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long optionId;
private String optionText;
private static final long serialVersionUID = 1L;
#ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
#JoinColumn(name = "questionId")
private Question question;
// omitting getters and setters
}
, answer
#Entity
public class Answer implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long answerId;
private String answerCorrect;
#OneToOne(mappedBy = "answer", cascade = CascadeType.ALL)
private Question question;
// omitting getters and setters
}
now every thing works good, but where should I save
Number of Correct Answers.
Number of Wrong Answers.
Result of quiz (Pass/Fail)

Related

How to make JPA query method about onetomany?

I'm stuck at deal with this problem. I have 'Review Entity', and 'Heart Entitiy'. And I tried to show them homepage and detailpage separately!
Long countHeartByBookReviewId(Long bookReview_id);
i used jpa query method for showing how many heart it gets in details page..
and now i want to show review descending related to heart count in main page!
how can i make the code..?
#Entity
public class BookReview extends Timestamped {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
private Long id;
...
#Column
private String review;
#JoinColumn(name = "member_id", nullable = false)
#ManyToOne(fetch = FetchType.EAGER)
private Member member;
#OneToMany(mappedBy = "bookReview" , cascade = CascadeType.REMOVE)
private List<Comment> comment;
#JsonIgnore
#OneToMany(mappedBy = "bookReview", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Heart> heart;
and the other entitiy is here.
public class Heart {
#GeneratedValue(strategy = GenerationType.AUTO)
#Id
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "bookReview_id")
private BookReview bookReview;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "member_id")
private Member member;
and this is function for get menthod...
public ResponseDto<?> getHome() {
List<BookReview> book_review = book_reviewRepository.findAllByOrderByHeartDesc();
List<HomeResponseDto> book_reviewResponseDtoList = new ArrayList<>();
for (BookReview home : book_review) {
book_reviewResponseDtoList.add(HomeResponseDto.builder()
.id(home.getId())
.username(home.getMember().getUsername())
.thumbnail(home.getThumbnail())
.title(home.getTitle())
.author(home.getAuthor())
.publisher(home.getPublisher())
.review(home.getReview())
.heart(heartRepository.countHeartByBookReviewId(home.getId()))
.createdAt(home.getCreatedAt())
.modifiedAt(home.getModifiedAt())
.build()
);
}
return ResponseDto.success(book_reviewResponseDtoList);
}
please help me ......

One table has two same joins in another table

I have one table called image and another table called duplicate. There are two OneToMany relations are associated.
I am not quite sure whether below implementation is the right approach for that. Moreover whether we require that second private List<DuplicateEntity> duplicateEntities2; ?
ImageEntity:
#Entity
#Table(name = "image")
public class ImageEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "filename")
private String fileName;
#OneToMany(mappedBy = "imageEntity1")
private List<DuplicateEntity> duplicateEntities1;
#OneToMany(mappedBy = "imageEntity2")
private List<DuplicateEntity> duplicateEntities2;
}
DuplicateEntity:
#Entity
#Table(name = "duplicate")
public class DuplicateEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "image_a_id")
private ImageEntity imageEntity1;
#ManyToOne
#JoinColumn(name = "image_b_id")
private ImageEntity imageEntity2;
}

org.hibernate.PropertyAccessException: Could not set field value [STRING] value by reflection for String

Does the #Embeddable for #ManyToMany relations and additional columns, works with String?
I do not use #Generated Value for #Id
Because my Entity ApplikationUser
#Id
#Column(length = 128)
private String applikationUserId;
by business logic has always an Id
Here my code:
#EmbeddedId
private ApplikationUserPopupMessageId applikationUserPopupMessageId;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("applikationUserId")
private ApplikationUser applikationUser;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("popupMessageId")
private PopupMessage popupMessage;
#Column(name = "gelesen")
private boolean gelesen = false;
#Embeddable
public class ApplikationUserPopupMessageId implements Serializable {
#Column(name = "applikation_user_id")
private String applikationUserId;
#Column(name = "popup_message_id")
private Long popupMessageId;
#Entity
#Table
public class PopupMessage {
#Id
#GeneratedValue
#Column(length = 128)
private Long messageId;
private String title;
private String message;
#OneToMany(
mappedBy = "applikationUser",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<ApplikationUserPopupMessage> applikationUserPopupMessages = new ArrayList<>();
#Entity
public class ApplikationUser implements UserDetails {
/**
*
*/
private static final long serialVersionUID = -5517804528054972083L;
#Id
#Column(length = 128)
private String applikationUserId;
#Column
private String password;
#ManyToOne
#JoinColumn(name = "idRole")
private Role role;
private boolean enabled = true;
#OneToMany(
mappedBy = "popupMessage",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<ApplikationUserPopupMessage> applikationUserPopupMessages = new ArrayList<>();
EDIT - 23.11.2020
Regards the lack of interest, its seems to be possible to us #Embeddable with String?
Instantiate applikationUserPopupMessageId:
#Entity
public class ApplikationUserPopupMessage {
#EmbeddedId
private ApplikationUserPopupMessageId applikationUserPopupMessageId = new ApplikationUserPopupMessageId();
}
That's known issue
Just put getters and setters for the according properties in your #Embeddable.
Does it help if you annotate your entity class with Access level to Field
#Entity(access = AccessType.FIELD)

Confusion with mapping in hibernate

I currently have 3 tables Assessment, Question and QuestionOption. Each assessment has some questions and each question has some question options. Initially I started our with #OneToMany mappings for these but later one due to the fields that I have I had to had composite keys in Question so the entire mapping changed. I am not satisfied with the current state. Can someone help me in mapping the tables.
The main reason I had to do this was that while instering questions, I realised that question number can be the same across multiple assessments. So I made it a composite key with questionNumber+assessmentId. Also the same thought process with question option. where the same question options can exist along different questions. How can and avoid this and keep it simple.
Assessment
#Entity
#JsonIgnoreProperties({"questionList"})
public class Assessment {
#Id
private String assessmentId;
private String assessmentTopic;
private String assessmentSubTopic;
private String assessmentLevel;
private String createdBy;
private String rating;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "assessment", fetch = FetchType.LAZY)
private List<Question> questionList;
//Getters and setters
}
Question
#Entity
#Getter
#Setter
#JsonIgnoreProperties({"assessment"})
public class Question implements Serializable {
#EmbeddedId
private QuestionAssessmentKey questionAssessmentKey;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "assessmentId", insertable = false, updatable = false)
private Assessment assessment;
private String questionText;
private String questionURL;
private QuestionStatus questionStatus;
// private int questionNumber;
private QuestionTypes questionType;
//Getters and Setters
}
QuestionAssessmentKey- The composite key
#Embeddable
public class QuestionAssessmentKey implements Serializable {
private int questionNumber;
private String assessmentId;
//Getters and setters
}
QuestionOption
#Entity
public class QuestionOption {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int questionOptionId;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumns({
#JoinColumn(name="assessmentId", referencedColumnName = "assessmentId"),
#JoinColumn(name="questionNumber", referencedColumnName = "questionNumber")
})
private Question question;
private Character questionOption;
private String questionOptionText;
//Getters and Setters
}

Hibernate annotation mapping, complicated diagram

I have some big problems with making a proper mapping for delivered diagram. It looks like this:
Now, so far I did this, hopefully its ok (ommited getters/setters). You'll notice that USERS has DOMAIN_ID, ignore it as it is not full diagram.
FunctionalityGroup
#Entity
#Table(name = "FUNCTIONALITY_GROUP")
public class FunctionalityGroup implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FUNCTIONALITY_GROUP_ID")
private Long functionalityGroupId;
#Column(name = "FUNCTIONALITY_GROUP_NM")
private String functionalityGroupName;
#Column(name = "FUNCTIONALITY_GROUP_DESC")
private String functionalityGroupDesc;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "funcionalityGroupId")
private List<Functionality> functionalityList;
}
Functionality
#Entity
#Table(name = "FUNCTIONALITY")
public class Functionality implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FUNCTIONALITY_ID")
private Long functionalityId;
#Column(name = "FUNCTIONALITY_NM")
private String functionalityGroupName;
#Column(name = "FUNCTIONALITY_DESC")
private String functionalityGroupDesc;
#Column(name = "FUNCTIONALITY_GROUP_ID")
private Long funcionalityGroupId;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "ROLE_FUNCTIONALITY",
joinColumns = {#JoinColumn(name = "FUNCTIONALITY_ID")},
inverseJoinColumns = {#JoinColumn(name = "ROLE_ID")})
private List<Role> roleList;
}
Role
#Entity
#Table(name = "ROLE")
public class Role implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ROLE_ID")
private Integer roleId;
#Column(name = "ROLE_NM")
private String roleName;
#Column(name = "ROLE_DESC")
private String roleDesc;
#Column(name = "OBJECT_TYPE")
private String objectType;
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "roleList")
private List<Functionality> functionalityListy;
}
Users
#Entity
#Table(name = "USERS")
public class Users implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "USER_DESC")
private String userDesc;
#Column(name = "FIRST_NM")
private String firstNM;
#Column(name = "LAST_NM")
private String lastNM;
#Column(name = "IS_ENABLED")
private String isEnabled;
}
I have no idea how Role_Member and Role_Member_Entry should be mapped and handled withing object world, could somebody give me some hits? Thanks!
Normally I'd connect Users with Role as Many to Many, but the entity Role_Member_Entry ruins everything.

Categories