patternjavaModerate
Inserting data in 3 tables of a database with JPA
Viewed 0 times
tableswithdatabaseinsertingdatajpa
Problem
I am starting a personal project and my first step is to insert a lot of statuses from tweeter in a database along with it's user and place (if applicable).
This is the database structure:
Pretty much a user or a place can have many statuses.
What my main question is, is since I'm new to JPA if I'm using an efficient way to insert the data fetched from the Twitter API in my database.
This is how I do it:
```
private void jInsertButtonActionPerformed(java.awt.event.ActionEvent evt) {
List status = TwitterTools.search(new Query("a"));
for (Status tweet : status) {
//Status tweet = status.get(0);
insertUser(tweet.getUser());
if (tweet.getPlace() != null) {
insertPlace(tweet.getPlace());
}
EntityTransaction userTransaction = _em.getTransaction();
userTransaction.begin();
sqlmanagement.Status myStatus = new sqlmanagement.Status();
myStatus.setId(tweet.getId());
myStatus.setText(tweet.getText());
myStatus.setCreatedAt(tweet.getCreatedAt());
myStatus.setFavoriteCount(tweet.getFavoriteCount());
myStatus.setRetweetCount(tweet.getRetweetCount());
myStatus.setIsoLang(tweet.getLang());
myStatus.setInReplyToStatusId(tweet.getInReplyToStatusId());
myStatus.setSource(tweet.getSource());
if (tweet.getPlace() != null) {
myStatus.setPlaceId(_em.find(sqlmanagement.Place.class, tweet.getPlace().getId()));
myStatus.setGeolocationLatitude(tweet.getGeoLocation().getLatitude());
myStatus.setGeolocationLongitude(tweet.getGeoLocation().getLongitude());
}
myStatus.setUserId(_em.find(sqlmanagement.User.class, tweet.getUser().getId()));
_em.persist(myStatus);
userTransaction.commit();
}
}
This is the database structure:
Pretty much a user or a place can have many statuses.
What my main question is, is since I'm new to JPA if I'm using an efficient way to insert the data fetched from the Twitter API in my database.
This is how I do it:
```
private void jInsertButtonActionPerformed(java.awt.event.ActionEvent evt) {
List status = TwitterTools.search(new Query("a"));
for (Status tweet : status) {
//Status tweet = status.get(0);
insertUser(tweet.getUser());
if (tweet.getPlace() != null) {
insertPlace(tweet.getPlace());
}
EntityTransaction userTransaction = _em.getTransaction();
userTransaction.begin();
sqlmanagement.Status myStatus = new sqlmanagement.Status();
myStatus.setId(tweet.getId());
myStatus.setText(tweet.getText());
myStatus.setCreatedAt(tweet.getCreatedAt());
myStatus.setFavoriteCount(tweet.getFavoriteCount());
myStatus.setRetweetCount(tweet.getRetweetCount());
myStatus.setIsoLang(tweet.getLang());
myStatus.setInReplyToStatusId(tweet.getInReplyToStatusId());
myStatus.setSource(tweet.getSource());
if (tweet.getPlace() != null) {
myStatus.setPlaceId(_em.find(sqlmanagement.Place.class, tweet.getPlace().getId()));
myStatus.setGeolocationLatitude(tweet.getGeoLocation().getLatitude());
myStatus.setGeolocationLongitude(tweet.getGeoLocation().getLongitude());
}
myStatus.setUserId(_em.find(sqlmanagement.User.class, tweet.getUser().getId()));
_em.persist(myStatus);
userTransaction.commit();
}
}
Solution
What my main question is, is since I'm new to JPA if I'm using an efficient way to insert the data fetched from the Twitter API in my database.
Well, it's not entirely bad, I understand that you need it because only your
First a nitpick:
Whenever you have this pattern in your code:
i.e. a sequence of
Then you should consider making a method in the class for
This will hopefully make it easier to avoid forgetting one of the properties, and will significantly reduce code duplication if you're using it from more than one location.
You could also apply the Delegation Pattern to set the tweet directly and add setters and getters that would redirect to the tweet.
You could also use some serialization/de-serialization to setup your SQLManagement-related object easier, it is a bit of an overkill though to do it that way.
I like that you are using EntityManagers and JPA, so that you're not doing this using the
Well, it's not entirely bad, I understand that you need it because only your
sqlmanagement.XXX classes are annotated with @Entity. You could improve the methods that you are using for it though.First a nitpick:
sqlmanagement is a class and should be written in PascalCase, so SqlManagement or SQLManagement.Whenever you have this pattern in your code:
myStatus.setId(tweet.getId());
myStatus.setText(tweet.getText());
myStatus.setCreatedAt(tweet.getCreatedAt());
myStatus.setFavoriteCount(tweet.getFavoriteCount());
myStatus.setRetweetCount(tweet.getRetweetCount());
myStatus.setIsoLang(tweet.getLang());
myStatus.setInReplyToStatusId(tweet.getInReplyToStatusId());
myStatus.setSource(tweet.getSource());i.e. a sequence of
objA.setXXX(objB.getXXX());Then you should consider making a method in the class for
objA, in this case:public void setFromTweet(Tweet tweet) {
this.id = tweet.getId();
this.text = tweet.getText();
...
this.isoLang = tweet.getLang();
this.inReplyToStatusId = tweet.getInReplyToStatusId();
this.source = tweet.getSource();
}This will hopefully make it easier to avoid forgetting one of the properties, and will significantly reduce code duplication if you're using it from more than one location.
You could also apply the Delegation Pattern to set the tweet directly and add setters and getters that would redirect to the tweet.
You could also use some serialization/de-serialization to setup your SQLManagement-related object easier, it is a bit of an overkill though to do it that way.
I like that you are using EntityManagers and JPA, so that you're not doing this using the
java.sql.Connection interface directly. Another nitpick though, in Java, field names should not start with underscore so _em should be em.Code Snippets
myStatus.setId(tweet.getId());
myStatus.setText(tweet.getText());
myStatus.setCreatedAt(tweet.getCreatedAt());
myStatus.setFavoriteCount(tweet.getFavoriteCount());
myStatus.setRetweetCount(tweet.getRetweetCount());
myStatus.setIsoLang(tweet.getLang());
myStatus.setInReplyToStatusId(tweet.getInReplyToStatusId());
myStatus.setSource(tweet.getSource());public void setFromTweet(Tweet tweet) {
this.id = tweet.getId();
this.text = tweet.getText();
...
this.isoLang = tweet.getLang();
this.inReplyToStatusId = tweet.getInReplyToStatusId();
this.source = tweet.getSource();
}Context
StackExchange Code Review Q#60051, answer score: 15
Revisions (0)
No revisions yet.