mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Add ObjectReference, and change UnitOfWorkImpl to use ObjectReference.
This commit is contained in:
parent
379fd71c9c
commit
5555d1f658
@ -1,25 +1,35 @@
|
||||
package com.pmease.commons.hibernate;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import com.pmease.commons.util.ObjectReference;
|
||||
|
||||
@Singleton
|
||||
public class UnitOfWorkImpl implements UnitOfWork, Provider<Session> {
|
||||
|
||||
private final Provider<SessionFactory> sessionFactoryProvider;
|
||||
|
||||
private final ThreadLocal<Stack<Session>> sessionStack = new ThreadLocal<Stack<Session>>() {
|
||||
private final ThreadLocal<ObjectReference<Session>> sessionReferenceHolder = new ThreadLocal<ObjectReference<Session>>() {
|
||||
|
||||
@Override
|
||||
protected Stack<Session> initialValue() {
|
||||
return new Stack<Session>();
|
||||
protected ObjectReference<Session> initialValue() {
|
||||
return new ObjectReference<Session>() {
|
||||
|
||||
@Override
|
||||
protected Session openObject() {
|
||||
return sessionFactoryProvider.get().openSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeObject(Session session) {
|
||||
session.close();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
@ -30,20 +40,11 @@ public class UnitOfWorkImpl implements UnitOfWork, Provider<Session> {
|
||||
}
|
||||
|
||||
public void begin() {
|
||||
Session session;
|
||||
if (sessionStack.get().isEmpty())
|
||||
session = sessionFactoryProvider.get().openSession();
|
||||
else
|
||||
session = sessionStack.get().peek();
|
||||
sessionStack.get().push(session);
|
||||
sessionReferenceHolder.get().increase();
|
||||
}
|
||||
|
||||
public void end() {
|
||||
Preconditions.checkState(!sessionStack.get().isEmpty(),
|
||||
"Not balanced calls to UnitOfWork.begin() and UnitOfWork.end()");
|
||||
Session session = sessionStack.get().pop();
|
||||
if (sessionStack.get().isEmpty())
|
||||
session.close();
|
||||
sessionReferenceHolder.get().decrease();
|
||||
}
|
||||
|
||||
public Session get() {
|
||||
@ -51,9 +52,7 @@ public class UnitOfWorkImpl implements UnitOfWork, Provider<Session> {
|
||||
}
|
||||
|
||||
public Session getSession() {
|
||||
Preconditions.checkState(!sessionStack.get().isEmpty(),
|
||||
"Make sure to begin a work first by calling UnitOfWork.begin().");
|
||||
return sessionStack.get().peek();
|
||||
return sessionReferenceHolder.get().getObject();
|
||||
}
|
||||
|
||||
public SessionFactory getSessionFactory() {
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
package com.pmease.commons.util;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public abstract class ObjectReference<T> {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
private T object = null;
|
||||
|
||||
protected abstract T openObject();
|
||||
|
||||
public synchronized T getObject() {
|
||||
Preconditions.checkState(count > 0, "Reference count has to be increased first.");
|
||||
|
||||
if (object == null) {
|
||||
object = openObject();
|
||||
Preconditions.checkState(object != null);
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
public synchronized void increase() {
|
||||
count++;
|
||||
}
|
||||
|
||||
public synchronized void decrease() {
|
||||
if (count > 0)
|
||||
count--;
|
||||
if (count == 0 && object != null) {
|
||||
closeObject(object);
|
||||
object = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void closeObject(T object);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user