Getting repeated entries in table on a one-to-many relation - java

I'm learning jpa and decided to do a basic webapp where a User can post Messages, so a user have many messages. The problem is that when I add a message to the User's messages collection, I get duplicated entries in the Message table. (note I have two tables with the owner Id on Message, there is no join table).
This is the conversation:
First message -> Larry says: Hello John
Second message -> Larry says: Are you there?
Third Message -> John says: Yep
Fourth Message -> Larry says: ok
Fifth Message -> John says: fine
This is what I get in the screen:
Larry: Hello John
Larry Hello John
Larry: Are you there?
John: Yep
Larry: Hello John
Larry: Are you there?
Larry: ok
John: Yep
John: fine
The table content is:
+----+----------------+----------+
| id | message | owner_id |
+----+----------------+----------+
| 1 | Hello John | NULL | <- Why the NULL fields?
| 2 | Hello John | NULL |
| 3 | Are you there? | NULL |
| 4 | Yep | NULL |
| 5 | Hello John | 1 |
| 6 | Are you there? | 1 |
| 7 | ok | 1 |
| 8 | Yep | 2 |
| 9 | fine | 2 |
+----+----------------+----------+
These are the classes I have and its mappings.
#Entity
public class User implements Serializable {
#Id
#GeneratedValue
private Long id;
private String username;
private String password;
#OneToMany (fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name="owner_id")
private List<Message> messages; ...and all of its corresponding getters and setters
#Entity
public class Message implements Serializable {
#Id
#GeneratedValue
private Long id;
private String message;
#ManyToOne
private User owner; //...and all of its corresponding getters and setters
This is the relevant jsp scriptlet section which saves the user:
User user = (User)session.getAttribute("user");
user.getMessages().add(new Message(request.getParameter("message")));
FactoryDAO.getInstance().getUserDAO().update(user);
update(user) method:
public void update(User user) {
initEntityManager(); <- method in the superclass which initializes the entityManager
tx.begin();
entityManager.merge(user);
entityManager.flush();
tx.commit();
closeEntityManager();
}
Can you help me to find out what is wrong here?
Thanks!

It might have something to do with the way you're creating new User objects (not shown in your code).
Other than that, a couple of things you could try:
Use persist and not merge in the update method
Use a Set instead of a List for storing messages
Be sure to override equals and hashCode in both of your entities

I fix the problem doing as follows:
<%
User user = (User)session.getAttribute("user");
Message message = new Message(request.getParameter("message"));
message.setOwner(user);
FactoryDAO.getInstance().getMessageDAO().update(message);
%>
I have set a owner to a message instead of a message to a user.
I still don't understand why my first version didn't work as I expected.

Related

I am trying to connect 2 tables to have same rev number using hibernate envers?

I have customer entity that have List of accounts and each entity have audited tables,so tables generated will be :
(CUSTOMERS
,ACCOUNTS
,CUSTOMERS_AUD
,ACCOUNTS_AUD)
how can I connect the change of accounts with the change of customer in one rev number? hibernate envers gives separated version (rev number) for each table ?
The generated tables of my code:
CUSTOMERS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|ACCOUNTID|
|:----|------:|:-------:|:----:|:---------:|:-------:|
| 1 | 1 | 0 |Ann |1234567897 |1 |
| 1 | 3 | 1 |Alex |1234567897 |1 |
| 1 | 5 | 1 |Alex |7777777777 |1 |
ACCOUNTS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|
|:-----------|------:|:-------:|:----:|:---------:|
| 1 | 2 | 0 |Ann |1234567897 |
| 1 | 4 | 1 |Alex |7777777777 |
SAMPLE ENTITIES
#Entity
#Table(name="CUSTOMERS")
#Audited
public class Customer implements Serializable {
.
.
#ManyToOne
#org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.REPLICATE)
#JoinColumn(name="ACCOUNTNUMBERCOMBOBOXID", nullable=true)
private Account accountNumberComboBox;
public static final String REF_CUSTOMERS_ACCOUNTS = "refCustomersAccounts";
#OneToMany(mappedBy = "refCustomers")
#org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.REPLICATE)
private List<Account> refCustomersAccounts;
.
.
.
}
#Entity
#Table(name="ACCOUNTS")
#Audited
public class Account implements Serializable {
.
.
public static final String REF_CUSTOMERS = "refCustomers";
#ManyToOne
#org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.REPLICATE)
#JoinColumn(name="REFCUSTOMERSID", nullable=true)
private Customer refCustomers;
.
.
.
}
THE RESULTS THAT I WANT
CUSTOMERS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|ACCOUNTID|
|:----|------:|:-------:|:----:|:---------:|:-------:|
| 1 | 1 | 0 |Ann |1234567897 |1 |
| 1 | 2 | 1 |Alex |1234567897 |1 |
| 1 | 3 | 1 |Alex |7777777777 |1 |
ACCOUNTS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|
|:-----------|------:|:-------:|:----:|:---------:|
| 1 | 1 | 0 |Ann |1234567897 |
| 1 | 2 | 0 |Ann |1234567897 |
| 1 | 3 | 1 |Alex |7777777777 |
Spring boot application
#SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
#Autowired
private ApplicationContext context;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
CustomerRepo customerRepo = context.getBean(CustomerRepo.class);
AccountRepo accountRepo = context.getBean(AccountRepo.class);
AccountTypeRepo accountTypeRepo = context.getBean(AccountTypeRepo.class);
Accounts account = new Accounts();
Customers customer = new Customers();
customer.setId(1L);
account.setId(1L);
account.setFromDate(new Date());
account.setToDate(new Date());
account.setNewAcountNumber("1234567897");
account.setOwner("Ann");
customer.setAccountNumber(account.getNewAcountNumber());
customer.setCode("CODE");
customer.setName(account.getOwner());
customer.setFromDate(new Date());
customer.setToDate(new Date());
customer.setAccountNumberComboBox(account);
accountRepo.save(account);
customerRepo.save(customer);//0
customer.setName("Alex");
customerRepo.save(customer);//1
account.setNewAcountNumber("7777777777");
accountRepo.save(account);
}
}
Account Repo
#Repository
public interface AccountRepo extends CrudRepository<Accounts,Long> {
}
Customer Repo
#Repository
public interface CustomerRepo extends CrudRepository<Customers, Long> {
}
The revision number is associated with the transaction, so whatever operations you perform in a single transaction will be audited and stored with the same revision number, always.
Since you did not show your persistence code I can only guess at this point that the code is likely saving the Customer entity in one transaction and in a subsequent transaction you're saving the Account entity.
If you save them both within the same transaction, they'll get the same revision number assigned to their audit rows.

How create structure and display comments nested Spring Boot with AngularJs

I want create comments with sub comments nested, like hierarchy. I donĀ“t know if create structure like that
1# First structure
public class Comment{
private Long id;
private String comment;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(nullable=true,name="parent_id")
private Comment parent; //Parent comment
#OneToMany(fetch=FetchType.EAGER)
private Set<Comment> subComments; //Sub comments
Or only creat that structure. 2# Second structure
public class Comment{
private Long id;
private String comment;
private Long parent_id;//Parent comment
If I create the second structure with parent_id, my json will be like this.
| id | comment | parent |
| 1 | comment1 | 0 |
| 2 | comment2 | 1 |
| 3 | comment3 | 2 |
| 4 | comment4 | 1 |
| 5 | comment5 | 4 |
| 6 | comment6 | 4 |
| 7 | comment7 | 6 |
| 8 | comment8 | 7 |
| 9 | comment9 | 0 |
My problem is how to create nested comments with Spring Boot and AngularJS? What the correct structure to create and display?
I want to display comments like that. My jsfiddle example about that.
Comment #1 (deepness = 0): comment 1
Reply #4 of #1 (deepness = 1): reply comment 1
Reply #8 of #4 (deepness = 2): reply of reply comment 3
Reply #9 of #8 (deepness = 3): reply of reply of reply comment 3
Comment #2 (deepness = 0): comment 2
Reply #5 of #2 (deepness = 1): reply comment 2
Comment #3 (deepness = 0): comment 3
Reply #6 of #3 (deepness = 1): reply comment 3
Reply #7 of #3 (deepness = 1): reply comment 3

Java - building a new members block

I am new to Java Spring Boot and I am looking to create a set of admin dashboard components.
One is a "new members" in the last 28 days block.
So the user table will look something like this
id | email | password | registeredDate
1 | a#gmail.com | $2hasdhdahjasd | 12/01/2017
2 | b#gmail.com | $2hdsfdsfhgjsd | 15/01/2017
3 | c#gmail.com | $4sdfdggfdsfsd | 17/01/2017
4 | d#gmail.com | $6hasdfdahjasg | 01/02/2017
5 | e#gmail.com | $9fdfdfdahjasg | 03/02/2017
6 | f#gmail.com | $89dddfdahjasg | 07/02/2017
7 | g#gmail.com | $fghgdfdahjasg | 07/02/2017
--
so in this instance - say its February - "4+25%"
What kind of algorithms/logic do I start with to get the correct data?
// 28 days ago
Calendar thresholdPast = Calendar.getInstance();
thresholdPast.set(Calendar.HOUR_OF_DAY,0);
thresholdPast.set(Calendar.MINUTE,0);
thresholdPast.set(Calendar.SECOND,0);
thresholdPast.add(Calendar.DATE,-28);
I am using a JPA to get the data out of the system - if there is a way of creating a line that will fetch these stats?
public interface TblLoginRepository extends JpaRepository<TblLogin, String> {
long count();
List<TblLogin> findAll();
}

Is it possbile to have a null value on Example table on Cucumber Scenario Outline? [duplicate]

This question already has answers here:
Cucumber Scenario Outline: Passing empty string " " as value in Examples table
(2 answers)
Closed 5 years ago.
Here is my example table on my scenario outline, some does not have value, is this possible?
Examples:
|ID | UserName | Password | Contact1 | Number |
|ID1 | username1 | password1 | Phone | 111 222 4444 |
|ID2 | username2 | password2 | | |
|ID3 | username3 | password3 | Email | a#a.com |
|ID4 | username4 | password4 | | |
The empty value will be considered a String if the feature step looks something like this:
Given ...
When I enter my "<Username>" and "<Password>"
And I enter my "<Contact>"
And I enter my "<Number>"
Then ...
You can manage the empty string inside the step definition:
#When("^I enter my \"([^\"]*)\"$")
public void I_enter_my(String contact) throws Throwable {
// Handle empty string as null
throw new PendingException();
}
Just an exmple, not sure if the code will work. Hope it helps.

Hibernate. How to get non-uniform the tree from result?

I have a fairly simple problem. I need to get likeness a tree from the result of the stored procedure. But unfortunately all the examples I've found, used or tables, or uniform structure of the tree.
Stored procedure can return:
| firm_id | index_id | value |
| 1 | 101 | 123 |
| 1 | 102 | 123 |
| 2 | 101 | 123 |
I'm trying to divide by class:
#Entity
#NamedNativeQuery(
name = "getReport",
resultClass = Report.class,
query = "{call myProc(?)}",
callable = true
)
public class Report {
#Id
#Column(name = "firm_id")
private long firmId;
#Embedded
private List<Index> indexList;
// getters and setters
}
Second class:
#Embeddable
public class Index {
#Column(name = "index_id")
private long indexId;
#Column(name = "value")
private int value;
// getters and setters
}
As a result I get a null. I also tried using #ManyToOne/#OneToMany, but received "Table not found". What am I doing wrong?
Thank you for your attention.

Categories

Resources