JPA実装として人気だったHibernateですが、今後はEclipseLinkが主流になるらしい。
Hibernateつぶし? – ひがやすを blog
多対多のサンプルがWeb上に見つからなかったのでメモ。
[code lang=”ruby”]
CREATE TABLE IF NOT EXISTS `entries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`subject` varchar(255) NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
CREATE TABLE IF NOT EXISTS `categories_entries` (
`entry_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
PRIMARY KEY (`entry_id`,`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[/code]
こんなテーブルがあったとすると、entriesとcategoriesに対応するエンティティにそれぞれ次のフィールドを追加する。
[code lang=”java”]
@Entity
@Table(name = "entries")
class Entry implements Serializable {
@ManyToMany
@JoinTable(name="categories_entries",
joinColumns={@JoinColumn(name="entry_id")},
inverseJoinColumns={@JoinColumn(name="category_id")})
private Set<Category> categories = new HashSet<Category>();
// アクセッサメソッドも必要
}
@Entity
@Table(name = "categories")
class Category implements Serializable {
@ManyToMany(mappedBy="categories")
private Collection<Entry> entries = new ArrayList<Entry>();
// アクセッサメソッドも必要
}
[/code]
以下で永続化インスタンスを取得。
[code lang=”java”]
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JavaApplication1PU");
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("SELECT e FROM Entry e");
List<Entry> entries = q.getResultList();
Iterator<Entry> it = entries.iterator();
while (it.hasNext()) {
Entry entry = it.next();
logger.debug("id: {}", entry.getId());
logger.debug("subject: {}", entry.getSubject());
logger.debug("content: {}", entry.getContent());
Set<Category> categories = entry.getCategories();
Iterator<Category> itc = categories.iterator();
while (itc.hasNext()) {
Category category = itc.next();
logger.debug("category: {}", category.getName());
}
}
em.close();
emf.close();
[/code]
原因不明の病
一応これで動いたけど、SwingGUIアプリケーションだとタイミングによってなぜかエラーが出たり出なかったりする。まったく同じようなプロジェクトを作ったら何故かそっちはエラーが全く出ない。
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: Exception Description: Error compiling the query [SELECT e FROM Entry e]. Unknown entity type [Entry]. at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1328) at db.MyBlogSample.jButton1ActionPerformed(MyBlogSample.java:96) at db.MyBlogSample.access$000(MyBlogSample.java:30) at db.MyBlogSample$1.actionPerformed(MyBlogSample.java:57) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.Component.processMouseEvent(Component.java:6267) at javax.swing.JComponent.processMouseEvent(JComponent.java:3267) at java.awt.Component.processEvent(Component.java:6032) at java.awt.Container.processEvent(Container.java:2041) at java.awt.Component.dispatchEventImpl(Component.java:4630) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4460) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168) at java.awt.Container.dispatchEventImpl(Container.java:2085) at java.awt.Window.dispatchEventImpl(Window.java:2478) at java.awt.Component.dispatchEvent(Component.java:4460) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Caused by: Exception [EclipseLink-8034] (Eclipse Persistence Services - 2.0.2.v20100323-r6872): org.eclipse.persistence.exceptions.JPQLException Exception Description: Error compiling the query [SELECT e FROM Entry e]. Unknown entity type [Entry]. at org.eclipse.persistence.exceptions.JPQLException.entityTypeNotFound(JPQLException.java:483) at org.eclipse.persistence.internal.jpa.parsing.ParseTreeContext.classForSchemaName(ParseTreeContext.java:138) at org.eclipse.persistence.internal.jpa.parsing.SelectNode.getClassOfFirstVariable(SelectNode.java:327) at org.eclipse.persistence.internal.jpa.parsing.SelectNode.getReferenceClass(SelectNode.java:316) at org.eclipse.persistence.internal.jpa.parsing.ParseTree.getReferenceClass(ParseTree.java:439) at org.eclipse.persistence.internal.jpa.parsing.ParseTree.adjustReferenceClassForQuery(ParseTree.java:79) at org.eclipse.persistence.internal.jpa.parsing.JPQLParseTree.populateReadQueryInternal(JPQLParseTree.java:103) at org.eclipse.persistence.internal.jpa.parsing.JPQLParseTree.populateQuery(JPQLParseTree.java:84) at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:202) at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:173) at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:125) at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:109) at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1326) ... 28 more
一筋の光
一旦生成物を削除して実行したら直った。Javaは何故かこういうことが多いので注意が必要。
蛇足
JPA 2.0を使う場合はJava6推奨らしい。
投稿者紹介
-
私たちは、テクノロジに魅せられた個性あふれるメンバーによって構成された茨城県日立市に本社を構えるベンチャー企業です。
”テクノロジを通して「驚き」と「感動」を創造し、人々の「夢」と「笑顔」を支えます。” の経営理念をモットーに明るい未来を描き、ワクワクする企画提案を続けて参ります。
最近のエントリ
- レポート2019.10.28ユニキャストレストランを開催しました🍳
- レポート2019.08.29社内研修ワークショップ~マシュマロ・チャレンジ~
- レポート2019.08.06Computex/InnoVEX 出展者・通訳として参加してきました。
- レポート2018.06.12Computex 2018 レポート