我知道最佳做法是同时使用service和dao层,并在服务级别添加@Transactional注释.但在我的情况下,这意味着我的大多数服务类都是为了重复DAO方法而创建的......这非常令人恼火.
例如.
public interface FooDAO {
public List<FooVO> list(int cathegoryId);
public List<FooVO> list(int cathegoryId, int ownerId);
}
@Service
@Transactional
public class FooService {
protected @Autowired FooDAO dao;
public List<FooVO> list(int cathegoryId) {
dao.list(cathegoryId);
}
public List<FooVO> list(int cathegoryId, int authorId) {
dao.list(cathegoryId, authorId)
}
}
Run Code Online (Sandbox Code Playgroud)
那是多么愚蠢?
在大多数情况下,我真的不需要花哨的服务方法,因为通常这是一个例如.导管描述和与导管相匹配的实体列表.这就是为什么我在寻找简化的解决方案.像使用泛型来避免重复DAO一样辉煌:D http://www.javablog.fr/javahibernate-dont-repeat-the-dao-with-a-genericdao.html
我找到了答案.其中我读过 @Transactional注释属于哪里? 但仍然没有找到我的答案.
所以我想知道用@Transactional注释DAO方法真是个坏主意.灵感来自http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/#apistrategy我找到了一个解决方案.
如果:
**更新1**
它看起来像这样:
public interface FooDAO {
@Transactional(propagation = Propagation.MANDATORY, readOnly=true)
public List<FooVO> list(int cathegoryId);
...
}
@Service
public class …Run Code Online (Sandbox Code Playgroud) 我正在使用使用Jetty 9.0.2的SparkJava 2.2.
我得到Jetty抛出的"Form too large"异常.如果我直接使用Jetty,我已经知道如何解决这个问题:
http://www.eclipse.org/jetty/documentation/current/setting-form-size.html
问题:
现在我需要找到一种org.eclipse.jetty.server.Request.maxFormContentSize通过SparkJava 更改设置的方法.有没有办法做到这一点?
我必须注意其他方法(JVM_OPTS,System.setProperty)由于某些原因不适合我.我仍然得到同样的例外.
堆栈跟踪:
[qtp1858644635-27] ERROR spark.webserver.MatcherFilter -
java.lang.IllegalStateException: Form too large 308913>200000
at org.eclipse.jetty.server.Request.extractParameters(Request.java:334)
at org.eclipse.jetty.server.Request.getParameterMap(Request.java:765)
at javax.servlet.ServletRequestWrapper.getParameterMap(ServletRequestWrapper.java:193)
at spark.QueryParamsMap.<init>(QueryParamsMap.java:59)
at spark.Request.initQueryMap(Request.java:364)
at spark.Request.queryMap(Request.java:349)
at spark.webserver.RequestWrapper.queryMap(RequestWrapper.java:213)
at com.xyz.analytics.webservice.RequestTools.getRequestQueryMap(RequestTools.java:27)
at com.xyz.analytics.webservice.RequestTools.getMandrillQueryParams(RequestTools.java:22)
at com.xyz.analytics.webservice.Endpoints.lambda$initiateEndpointsAndExceptionHandlers$2(Endpoints.java:61)
at com.xyz.analytics.webservice.Endpoints$$Lambda$3/1485697819.handle(Unknown Source)
at spark.SparkBase$1.handle(SparkBase.java:311)
at spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:159)
at spark.webserver.JettyHandler.doHandle(JettyHandler.java:60)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:179)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:451)
at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:252)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:266)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:240)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:596)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:527)
at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)
我必须注意其他方法(JVM_OPTS,System.setProperty)对我不起作用.
好吧,调试器甚至不会在任何设置的断点处停止org.eclipse.jetty.server.handlerContextHandler...加上当它在org.eclipse.jetty.server.Request断点处停止时,_context属性为null.似乎SparkJava以不同的方式处理它.死路. …
由GroovyShell / Groovy脚本引起的内存泄漏(请参阅最后的GroovyEvaluator代码)。主要问题是(从MAT分析器复制粘贴):
由“ <系统类加载器>”加载的类“ java.beans.ThreadGroupContext”占用807,406,960(33.38%)个字节。
和:
由“ sun.misc.Launcher $ AppClassLoader @ 0x7004e9c80”加载的“ org.codehaus.groovy.reflection.ClassInfo $ ClassInfoSet $ Segment”的16个实例占用1,510,256,544(62.44%)字节
我们正在使用Groovy 2.3.11和Java8(确切地说是1.8.0_25)。
升级到Groovy 2.4.6不能解决问题。只是提高了内存使用一个 小 一点,ESP。非堆。
我们正在使用的Java参数:-XX:+ CMSClassUnloadingEnabled -XX:+ UseConcMarkSweepGC
顺便说一句,我已阅读https://dzone.com/articles/groovyshell-and-memory-leaks。当不再需要GroovyShell shell时,我们会将其设置为null。使用GroovyShell()。parse()可能会有所帮助,但这对我们来说不是一个选择-我们有10多个集合,每个集合由20-100个脚本组成,并且可以随时更改(在运行时)。
设置MaxMetaspaceSize也应该有所帮助,但这并不能真正解决根本问题,也不能消除根本原因。所以我仍在努力确定。
我创建了负载测试来重新创建问题(请参阅最后的代码)。当我运行它时:
正如我已经提到的,我正在使用MAT分析堆转储。因此,让我们检查Dominator树报告:
Hashmap占用了30%以上的堆。因此,让我们进一步分析它。让我们看看里面有什么。让我们检查哈希条目:
报告了38 830个条目。包括38780个条目,这些条目的键匹配“ .class Script。 ”。
另一件事,“重复的类”报告:
我们有400个条目(因为负载测试定义了400个G.script),所有这些条目都属于“ ScriptN”类。它们都持有对groovyclassloader $ innerloader的引用
我发现了类似的错误报告:https : //issues.apache.org/jira/browse/GROOVY-7498(请参阅最后的评论和屏幕截图)-通过将Java升级到1.8u51解决了他们的问题。但是,这对我们并没有招数。
我们的代码:
public class GroovyEvaluator
{
private GroovyShell shell;
public GroovyEvaluator()
{ …Run Code Online (Sandbox Code Playgroud) java ×2
annotations ×1
dao ×1
groovyshell ×1
java-8 ×1
jetty ×1
memory-leaks ×1
spark-java ×1
spring ×1
transactions ×1