I have a JPA project which searches tweets by keword and should persist the key - tweet pairs in the database. The project has the following entities :
Code:
**User** entity
@Entity
@Table(name="users")
public class User implements Serializable{
private static final long serialVersionUID = -2220172753332595462L;
@Id
@Column(name="user_id")
private long userId;
@Column(name="screen_name")
private String screenName;
@Column(name="profile_image_url")
private String profileImageUrl;
@Column(name="statuses_count")
private int statusesCount;
@OneToMany(mappedBy="user")
private List<Tweet> tweets;
**Hashtag** entity
Code:
@Entity
@Table(name="hashtags")
public class Hashtag implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="hashtag_id")
private int hastagId;
@Column(name="hashtag",unique=true)
private String hashtag;
**Keyword** entity
Code:
@Entity
@Table(name="keywords")
public class Keyword implements Serializable {
private static final long serialVersionUID = -1429681347817644570L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="key_id")
private int keyId;
@Column(name="key_name",unique=true)
private String key_name;
@ManyToMany(cascade=CascadeType.PERSIST)
@JoinTable(
name="tweet_keyword",
joinColumns={@JoinColumn(name="key_id",
referencedColumnName="key_id")},
inverseJoinColumns={@JoinColumn(name="tweet_id",
referencedColumnName="tweet_id")}
)
private Set<Tweet> tweets;
**Tweet** entity
Code:
@Entity
@Table(name="tweets")
public class Tweet implements Serializable{
private static final long serialVersionUID = -1041037108182045708L;
@Id
@Column(name="tweet_id")
private long tweetId;
@Column(name="tweet_text")
private String tweetText;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, length = 19)
private Date createdAt;
@Column(name="lang_code")
private String languageCode;
@ManyToOne(cascade=CascadeType.PERSIST,optional=false)
@JoinColumn(name = "user_id",referencedColumnName="user_id")
private User user;
@ManyToMany(cascade=CascadeType.PERSIST)
@JoinTable(
name="tweet_hashtag",
joinColumns={@JoinColumn(name="tweet_id", referencedColumnName="tweet_id")},
inverseJoinColumns={@JoinColumn(name="hashtag_id", referencedColumnName="hashtag_id")}
)
private Set<Hashtag> hashtags;
@ManyToMany(cascade=CascadeType.PERSIST)
@JoinTable(
name="tweet_url",
joinColumns={@JoinColumn(name="tweet_id", referencedColumnName="tweet_id")},
inverseJoinColumns={@JoinColumn(name="url_id", referencedColumnName="url_id")}
)
private Set<Url> urls;
**Url** entity
Code:
@Entity
@Table(name="urls")
public class Url implements Serializable{
/**
*
*/
private static final long serialVersionUID = -606690240421717136L;
@Id @GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="url_id")
private int urlId;
@Column(name="url",unique=true)
private String url;
Now I have a class for persisting a Keyword,
Code:
public class TweetPersistent {
private EntityManagerFactory emf;
private EntityManager em;
public TweetPersistent()
{
emf=Persistence.createEntityManagerFactory("mypu");
em=emf.createEntityManager();
}
em.getTransaction().begin();
Keyword oldKeyword=this.findKeyword(keyword.getKeyName());
if(oldKeyword!=null)
{
keyword.setKeyId(oldKeyword.getKeyId());
em.merge(keyword);
em.getTransaction().commit();
}
else
{
em.persist(keyword);
em.getTransaction().commit();
}
private Keyword findKeyword(String key)
{
return (Keyword) em.createQuery("SELECT k FROM keyword k where
k.key_name = :value1")
.setParameter("value1", key).getSingleResult();
}
}
As you can see in the Keyword Entity, it has a joinTable and therefore a field that can have a set of tweets.
So whenever I get a key and a set of tweets, first I make a user entity, a set of hashtags and urls out of that tweet. Then I have a new tweet entity object.
In the next step I add this tweet(these tweets) to the keyword entity object.
Now I persist this keyword.
Problem: it is a correct solution?
As you can see, if the keyword exists, I change the Id of keyword with the id of existing keyword and then merge it, otherwise persist it.
At the moment i get the folowing error :
Code:
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "Thread-3" javax.persistence.EntityNotFoundException: Unable to find model.twitter.entities.Tweet with id 619564340417576960
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:183)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:989)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:716)
at org.hibernate.type.EntityType.resolve(EntityType.java:502)
at org.hibernate.type.EntityType.replace(EntityType.java:366)
at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:549)
at org.hibernate.type.CollectionType.replace(CollectionType.java:690)
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:177)
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:407)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:344)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
at model.twitter.TweetPersistent.insertResults(TweetPersistent.java:47)
at controller.TweetController.save(TweetController.java:77)
at controller.TweetController.parse(TweetController.java:48)
at main.TwitterStreamConsumer.run(TwitterStreamConsumer.java:26)
at java.lang.Thread.run(Thread.java:745)
Thank you so much in advance.