저는 Hibernate를 사용하여 쿼리를 수행하는 Spring 3.0.0.RC1에서 매우 간단한 REST 컨트롤러 메소드를 만들었습니다. 쿼리를 완료하는 데 약 10 초가 소요됩니다. 나는 내 컨트롤러에 두 가지 요청을 할 수 있도록 이걸 의도로 만들었습니다.두 개의 스레드에서 같은 서비스와 DAO 사용하기
그런 다음 두 요청을 실행하고 MySQL (내 DB 백엔드)에서 "전체 프로세스 목록 표시"라는 쿼리를 실행합니다. 그리고 놀랍게도 한 가지 요청 만 있습니다. 하나의 요청은 성공할 것이다. 하나의 요청은 "org.hibernate.SessionException : Session is closed!"예외로 실패 할 것이다. 두 개 이상의 요청을하면 하나만 성공하고 다른 요청은 같은 방식으로 실패합니다. 그리고 여러 번 있어야하지만 항상 한 번에 하나의 쿼리 만있을 것입니다.
어떻게 될 수 있습니까? 어떤 제안? UserServiceImpl
여기에 있습니다 :<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/MyDb" />
<property name="username" value="angua" />
<property name="password" value="vonU" />
<property name="initialSize" value="2" />
<property name="maxActive" value="5" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>tld.mydomain.sample.entities.User</value>
<value>tld.mydomain.sample.entities.Role</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="flushMode" value="0" />
</bean>
<bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
<bean id="userService" parent="txProxyTemplate">
<property name="target">
<bean class="tld.mydomain.business.UserServiceImpl"/>
</property>
<property name="proxyInterfaces" value="tld.mydomain.business.UserService"/>
</bean>
<context:component-scan base-package="tld.mydomain"/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor" />
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="" p:suffix=".jsp"/>
<bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
<property name="encoding" value="ISO-8859-1"/>
<property name="contentType" value="application/json"/>
</bean>
그리고 마지막으로 내 컨트롤러 코드 :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.JsonView;
import tld.mydomain.sample.business.UserService;
@Controller
@RequestMapping("/exp/*")
public class ExperimentsController {
@Autowired
private UserService userService;
@Autowired
private JsonView jsonView;
@RequestMapping(value="/long", method = RequestMethod.GET)
public ModelAndView lang() {
ModelAndView mav = new ModelAndView(jsonView);
userService.longQuery("UserA");
userService.longQuery("UserB");
return mav;
}
}
UPDATE
는 여기에 내가 컨트롤러에 사용하는 구성은, 당신이 내 구성에 대해 조금 얘기하려면
public class UserServiceImpl extends AbstractCRUDServiceImpl<User, String> {
@SuppressWarnings("unchecked")
@Override
public List<User> longQuery(String username) {
String like = "0" + username + "-%";
return DAO.getSession().createCriteria(User.class).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(Order.asc("name"))
.createCriteria("interests").add(Restrictions.like("userPrefixedId", like))
.createCriteria("community").add(Restrictions.like("userPrefixedAuthorId", like))
.createCriteria("member").add(Restrictions.like("userPrefixedGroupId", like))
.add(Restrictions.isNotEmpty("skills"))
.list();
}
}
(쿼리를 의도적으로 느리게 만들어서 동시에 실행되는 여러 요구를 가진 많은 동시 쿼리가
) 데이터베이스에서 실행 된 그리고 당신은뿐만 아니라 내 AbstractCRUDServiceImpl 및 GenericCRUDDAO가 필요합니다 얼마나보고에 대한 오류 : GenericCRUDDAO에서
public abstract class AbstractCRUDServiceImpl<Entity extends PublishableEntity, PkID extends Serializable> implements CRUDService<Entity, PkID> {
protected GenericCRUDDAO<Entity, PkID> DAO = new GenericCRUDDAO<Entity, PkID>(dataType());
@Override
public void create(Entity entity) {
DAO.create(entity);
}
@Override
public void delete(Entity entity) {
DAO.create(entity);
}
@Override
public Entity read(PkID entityPk) {
return DAO.read(entityPk);
}
@Override
public void update(Entity entity) {
DAO.update(entity);
}
private Class<PkID> pkType = null;
@SuppressWarnings("unchecked")
public Class<PkID> pkType() {
if(pkType != null)
return pkType;
// Backup solution in case datatype hasn't been set
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType paramType = (ParameterizedType) type;
pkType = (Class<PkID>) paramType.getActualTypeArguments()[1];
} else if (type instanceof Class) {
pkType = (Class<PkID>) type;
}
return pkType;
}
private Class<Entity> dataType = null;
@SuppressWarnings("unchecked")
private Class<Entity> dataType() {
if(dataType != null)
return dataType;
// Backup solution in case datatype hasn't been set
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType paramType = (ParameterizedType) type;
dataType = (Class<Entity>) paramType.getActualTypeArguments()[0];
} else if (type instanceof Class) {
dataType = (Class<Entity>) type;
}
return dataType;
}
}
는 PublishableEntity입니다 내 모든 엔티티가 어디에서 유래했는지. 엔티티가 유효하며 된 toString 사용 또는 유사한이
public class GenericCRUDDAO<EntityType extends PublishableEntity, PkID extends Serializable> implements CRUDDAO<EntityType, PkID> {
public GenericCRUDDAO() {}
public GenericCRUDDAO(Class<EntityType> datatype) {
this.setDataType(datatype);
}
private static SessionFactory sessionFactory = null;
public void setSessionFactory(SessionFactory sf) {
System.err.println("Setting SessionFactory for class " + this.getClass().getName());
sessionFactory = sf;
}
private Session session = null;
public Session getSession() {
if(session != null) {
if(session.isOpen())
return session;
}
if(sessionFactory == null)
Util.logError("sessionFactory is null");
session = ((SessionFactory) sessionFactory).getCurrentSession();
return session;
}
public void create(EntityType entity)
{
getSession().save(entity);
}
@SuppressWarnings("unchecked")
public EntityType read(PkID id)
{
return (EntityType) getSession().get(dataType(), id);
}
public void update(EntityType entity)
{
getSession().update(entity);
}
public void delete(EntityType entity) {
getSession().delete(entity);
}
public void delete(PkID id)
{
EntityType entity = read(id);
getSession().delete(entity);
}
private Class<EntityType> dataType = null;
@SuppressWarnings("unchecked")
private Class<EntityType> dataType() {
if(dataType != null)
return dataType;
// Backup solution in case datatype hasn't been set
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType paramType = (ParameterizedType) type;
dataType = (Class<EntityType>) paramType.getActualTypeArguments()[0];
} else if (type instanceof Class) {
dataType = (Class<EntityType>) type;
}
return dataType;
}
public void setDataType(Class<EntityType> datatype) {
this.dataType = datatype;
}
}
내가 구성 및 코드를 만들 희망 할 때 어떤 부분이 그 자체로 유지 대를 게시 할 경우에는 확인과 같은 몇 가지 간단한 편의성 방법이있다 왜 내가 한 번에 하나의 쿼리 만 수행 할 수있는 것처럼 보이는 것인가?
건배
닉
아니 문제는, 내가 그것을 사용하는 UserSerivceImpl 및 AbstractCRUDSerivceImpl가 연장 및 GenericCRUDDAO을 포함하도록 게시물을 업데이트했습니다. 너무 빨리 내게로 돌아와 주셔서 고마워요. – niklassaers
Hehe, 우리는 같은 오류를 발견 한 것 같습니다. 당신의 도움을 주셔서 대단히 감사합니다. 나는 어떤 일이 일어 났는지 잘 모르겠다. 그러나 나는 당신의 대답에 대해 "투표"를 받아 들였을 때 "0"으로 내려 갔고, 다시 "위로"를 누르면 "이 답변을 편집하지 않으면" . 당신이 작은 편집을 할 수있는 기회라면 다시 투표 할 수 있습니까? ;-) – niklassaers
걱정하지 마세요. 하나의 작은 편집을 완료했습니다. –