spring, hibernate: fehlgeschlagen zu faul initialisieren einer Sammlung
Ich habe ein problem mit lazy-Initialisierung. Ich kann nicht finden eine Lösung.
Ausnahme:
[pool-1-thread-12] ERROR:12:20:14.840 o.h.LazyInitializationException - failed to lazily initialize a collection of role: de.beeld.forges.domain.Server.applications, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: de.beeld.forges.domain.Server.applications, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
[pool-2-thread-1] ERROR:12:20:14.840 o.s.s.support.MethodInvokingRunnable - Invocation of method 'readStatusCache' on target class [class de.beeld.forges.task.annotation.ScheduledProcessor$$EnhancerByCGLIB$$ee649dc3] failed
java.util.ConcurrentModificationException: null
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
hibernate.xml
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="standardDataSource" p:lobHandler-ref="defaultLobHandler">
<property name="annotatedClasses">
<list>
<value>de.beeld.forges.domain.Server</value>
<value>de.beeld.forges.domain.Application</value>
<value>de.beeld.forges.domain.Forge</value>
</list>
</property>
</property>
</bean>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
<!-- Read in DAOs from the hibernate package -->
<context:component-scan base-package="de.beeld.forges.dao" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="de.beeld">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
<context:exclude-filter expression="org.springframework.stereotype.Repository"
type="annotation" />
</context:component-scan>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
readStatusCache Methode:
public void readStatusCache() {
String execCommand = "java -jar ...";
List<Future<Map<Long, Integer>>> list = new ArrayList<Future<Map<Long, Integer>>>();
String serverName = null;
for (Server server : serviceFacade.getServers()) {
serverName = server.getName();
Callable<Map<Long, Integer>> worker = new ApplicationStatusReader2(server.getApplications(),
sshConnector, execCommand, serverName);
Future<Map<Long, Integer>> submit = this.serviceFacade.getExecutor().submit(worker);
list.add(submit);
}
for (Future<Map<Long, Integer>> future : list) {
//do stuff
}
}
Server.java
@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
public class Server implements DomainObject, Comparable<Server> {
private static final long serialVersionUID = -8920952435734596243L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true, nullable = false)
@NotEmpty
private String name;
@Column(nullable = false)
@NotEmpty
@Pattern(regexp = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$", message = "The ip must be in format xxx.xxx.xxx.xxx")
private String ip;
@Column(nullable = false)
@NotEmpty
private String fqdn;
@OneToMany(mappedBy = "server", fetch = FetchType.LAZY)
private List<Application> applications;
@Version
private int version;
//getter and setter
}
Application.java
@Entity
public class Application implements DomainObject {
private static final long serialVersionUID = -8127137156319959239L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Server server;
@Column(nullable = false)
@NotEmpty
private String name;
@Column(nullable = false)
@NotEmpty
private String location;
@Column(nullable = false)
@NotEmpty
private String binDir;
private String confDir;
private boolean isContainer = false;
private String containerDir;
private String startup = "startup.sh";
private String shutdown = "shutdown.sh";
@ManyToOne(fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
private Forge forge;
@ManyToOne(fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
private Application parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<Application> offsprings;
@NotEmpty
private String blueprint;
private Integer replaceable = 0;
private Integer running = 0;
@Version
private int version;
//getter and setter
}
Ich weiß wirklich nicht, warum ich kann nicht Lesen Sie die Liste der Anwendungen vom server
Wenn jemand helfen könnte wäre es toll.
InformationsquelleAutor spinner0815 | 2012-06-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wahrscheinlich, weil Sie beim festlegen der Anwendungen, die Sammlung zu lazy load. Also, wenn Sie zurückkehren aus dem ersten Aufruf serviceFacade.getServers(), meine Vermutung ist, dass Sie nicht mehr die Sitzung eröffnet, wurde verwendet, um das abrufen der Liste mit Server.
Als Ergebnis, wenn Sie den iterator durch die Anwendungen, die Sitzung war geschlossen, so kann es nicht geladen werden, der aktuelle Inhalt der Sammlung.
Haben Sie drei Möglichkeiten:
Vielen Dank für eine solche klare Lösung... Das war ein Alptraum für mich (ich suchte rund um das internet für 2 Stunden). Das Hauptproblem für mich ist, dass ich konnte nicht tun, 1 (die Methode wurde außerhalb der Feder-Objekt), PLUS ich arbeite auf dem desktop-app. Ich ging mit Hibernate.initialize(myModel.getRelatedCollection()); die feinen gearbeitet
InformationsquelleAutor Matt
Den zwei Schleifen
sind aufgerufen, durch zwei verschiedene threads gleichzeitig. Sie können überprüfen, ob dies der Fall durch die Synchronisierung der
readStatusCache()
Methode. Aber dies sollte getan werden, im Frühjahr Ebene. Sind Sie mit Transaktionen etc. richtig?Bitte Lesen Sie diese Antwort mehr auf thread-Sicherheit mit spring und hibernate. Spring-Hibernate verwendet, die in einer webapp,welche Strategien für Thread-sichere session-management
GenericDaoImpl extends HibernateDaoSupport
. Ich hoffe, du weißt, was ich meine.Es scheint ok. Der einzige Grund, der mir einfällt, werfen Sie Ihre stacktrace war. Also ich bin outa Munition mate. Viel Glück....
InformationsquelleAutor Thihara
Wenn ich die gleiche Ausnahme, die Lösung war, fügen Sie die @Transactional-annotation, um die Methode in der controller.
InformationsquelleAutor