Hibernate 4 と Spring 3 に問題があります。BoneCP も使用しています。多くの画像を含む記事を保存しようとしていますが、うまくいきます。ただし、任意の画像の ID を取得しようとすると、0 が返されます。ただし、データベースでは、すべてが正常に保存されます。問題は、実行後のIDが有効であるため、関係の永続化またはHibernateの理解のどこかにあると思いますが、見つけることができません。
私のファイル: spring-hibernate.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" autowire="autodetect">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.smiechmateusz.model.Article</value>
<value>com.smiechmateusz.model.Image</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<ref local="mainDataSource" />
</property>
</bean>
<bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/java" />
<property name="username" value="root"/>
<property name="password" value="toor"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="idleMaxAge" value="240"/>
<property name="maxConnectionsPerPartition" value="60"/>
<property name="minConnectionsPerPartition" value="20"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="10"/>
<property name="statementsCacheSize" value="50"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<context:annotation-config />
<context:component-scan base-package="com.smiechmateusz.dao" />
<bean id="hibernateConfiguration" factory-bean="&sessionFactory" factory-method="getConfiguration" />
<bean id="AbstractHibernateDAO" abstract="true"
class="com.smiechmateusz.dao.AbstractDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="ImageDAO" parent="AbstractHibernateDAO" class="com.smiechmateusz.dao.ImageDAO" />
<bean id="ArticleDAO" parent="AbstractHibernateDAO" class="com.smiechmateusz.dao.ArticleDAO" />
</beans>
AbstractDAO.java
package com.smiechmateusz.dao;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.PersistentObjectException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional()
public abstract class AbstractDAO<T extends Serializable>
{
private final Class<T> clazz;
@Autowired
SessionFactory sessionFactory;
public AbstractDAO(final Class< T> clazzToSet)
{
this.clazz = clazzToSet;
}
public T getById(final Long id)
{
if (id != null)
return (T) this.getCurrentSession().get(this.clazz, id);
return null;
}
public List<T> getAll()
{
return this.getCurrentSession().createQuery("from " + this.clazz.getName()).list();
}
public void create(final T entity)
{
if (entity != null)
{
try
{
this.getCurrentSession().persist(entity);
}
catch (PersistentObjectException e)
{
this.getCurrentSession().saveOrUpdate(entity);
}
}
}
public void update(final T entity)
{
if (entity != null)
{
this.getCurrentSession().merge(entity);
}
}
public void delete(final T entity)
{
if (entity != null)
this.getCurrentSession().delete(entity);
}
public void deleteById(final Long entityId)
{
final T entity = this.getById(entityId);
if (entity != null)
this.delete(entity);
}
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
protected final Session getCurrentSession()
{
return this.sessionFactory.getCurrentSession();
}
public List<T> getWithCriteria(List<Criterion> criteria)
{
Criteria c = this.getCurrentSession().createCriteria(this.clazz);
for (Criterion cr : criteria)
{
c.add(cr);
}
return c.list();
}
}
ImageDAO.java
package com.smiechmateusz.dao;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.smiechmateusz.model.Image;
@Service
@Transactional()
public class ImageDAO extends AbstractDAO
{
public ImageDAO()
{
super(Image.class);
}
}
記事DAO.java
package com.smiechmateusz.dao;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.smiechmateusz.model.Article;
@Service
@Transactional()
public class ArticleDAO extends AbstractDAO
{
public ArticleDAO()
{
super(Article.class);
}
}
Image.java
package com.smiechmateusz.model;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="Image")
public class Image implements Serializable
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
long id;
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
@JoinColumn(name="article")
Article article;
@Column(name="path")
String path;
@Column(name="type")
int type;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public Article getArticle()
{
return article;
}
public void setArticle(Article article)
{
this.article = article;
}
public String getPath()
{
return path;
}
public void setPath(String path)
{
this.path = path;
}
public int getType()
{
return type;
}
public void setType(int type)
{
this.type = type;
}
}
記事.java
package com.smiechmateusz.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="Article")
public class Article implements Serializable
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
long id;
@Column(name="images")
@OneToMany(targetEntity=com.smiechmateusz.model.Image.class, mappedBy="article",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
List<Image> images;
@Column(name="description")
String description;
@Temporal(TemporalType.DATE)
@Column(name="addDate")
Date addDate;
public Article()
{
this.images = new ArrayList<Image>();
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public List<Image> getImages()
{
return images;
}
public void setImages(List<Image> images)
{
this.images = images;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public Date getAddDate()
{
return addDate;
}
public void setAddDate(Date addDate)
{
this.addDate = addDate;
}
}
次のコードを使用してテストしています。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-hibernate.xml");
Configuration config = (Configuration) context.getBean("hibernateConfiguration");
new SchemaExport(config).create(true, true);
ArticleDAO ad = (ArticleDAO) context.getBean("ArticleDAO");
ImageDAO id = (ImageDAO) context.getBean("ImageDAO");
Article a = new Article();
Image i = new Image();
i.setPath("path");
i.setType(0);
i.setArticle(a);
a.setAddDate(new Date());
a.setDescription("desc");
Image i2 = new Image();
i2.setPath("path2");
i2.setType(1);
i2.setArticle(a);
List<Image> list = new ArrayList<Image>();
list.add(i);
list.add(i2);
ad.create(a);
a.setImages(list);
ad.update(a);
System.out.println(i.getId()); //Returns 0 instead of 1.
DB クエリ:
mysql> SELECT * FROM Image;
+----+-------+------+---------+
| id | path | type | article |
+----+-------+------+---------+
| 1 | path | 0 | 1 |
| 2 | path2 | 1 | 1 |
+----+-------+------+---------+
2 rows in set (0.00 sec)
編集:
記事 a の ID を取得しようとすると、有効な ID (1) が返されます。
System.out.println(a.getId());
1