# Inserting data in 3 tables of a database with JPA

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) {

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.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();
}
}

private void insertUser(User user) {
EntityTransaction userTransaction = _em.getTransaction();

userTransaction.begin();
sqlmanagement.User myUser = new sqlmanagement.User();

myUser.setId(user.getId());
myUser.setCreatedAt(user.getCreatedAt());
myUser.setFavoritesCount(user.getFavouritesCount());
myUser.setDescription(user.getDescription());
myUser.setFollowersCount(user.getFollowersCount());
myUser.setFriendsCount(user.getFriendsCount());
myUser.setIsFollowRequestSent(user.isFollowRequestSent());
myUser.setIsGeoEnabled(user.isGeoEnabled());
myUser.setIsVerified(user.isVerified());
myUser.setLang(user.getLang());
myUser.setName(user.getName());
myUser.setScreenName(user.getScreenName());
myUser.setStatusesCount(user.getStatusesCount());
myUser.setTimezone(user.getTimeZone());

_em.persist(myUser);
userTransaction.commit();
}

private void insertPlace(Place place) {
EntityTransaction userTransaction = _em.getTransaction();

userTransaction.begin();
sqlmanagement.Place myPlace = new sqlmanagement.Place();

myPlace.setId(place.getId());
myPlace.setCountryCode(place.getCountryCode());
myPlace.setFullName(place.getFullName());
myPlace.setShortName(place.getName());
myPlace.setType(place.getPlaceType());
myPlace.setUrl(place.getURL());

_em.persist(myPlace);
userTransaction.commit();
}

EntityManagerFactory _entityManagerFactory = Persistence.createEntityManagerFactory("TestingGroundPU");
EntityManager _em = _entityManagerFactory.createEntityManager();


I have a very simple testing platform where when I press the insert button this happens:

1. Fetch the tweets based on the query (currently an empty one)
2. For each tweet insert it's user in the User table
3. Then if there is a Place with the tweet insert it at the Place table
4. In the end insert the tweet in the Status table along with the User and Place (if applicable)

My 3 classes derived from the database are:

sqlmanagement.Place
sqlmanagement.User
sqlmanagement.Status


Basically what I want to know is if there is a more efficient way of doing it and/or cleaner.

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 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.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();

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.