I have this error, I am running hibernate version 5.5.3.Final in tomcat 10.0.7.
I am using hibernate Session, not EntityManager
[29-06-2021 15:45:12,482] [pool-125-thread-1] FATAL lt.cm.util.Reflection - java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException
at jdk.internal.reflect.GeneratedConstructorAccessor137.newInstance(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at lt.cm.util.Reflection.getNewInstance(Reflection.java:106)
at lt.cm.json.LTJsonParse.toJson(LTJsonParse.java:55)
at lt.json.LTJsonModel.toJson(LTJsonModel.java:91)
at lt.model.Device.toJson(Device.java:408)
at lt.websocket.ModelObj.getJson(ModelObj.java:44)
at lt.websocket.LTWSMessage.create(LTWSMessage.java:112)
at lt.websocket.LTWSManager.lambda$publish$0(LTWSManager.java:74)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1603)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408)
at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:736)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:159)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:661)
at lt.websocket.LTWSManager.publish(LTWSManager.java:54)
at lt.websocket.LTWSWrapper.lambda$newEvent$0(LTWSWrapper.java:37)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at lt.websocket.LTWSWrapper.newEvent(LTWSWrapper.java:36)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalStateException: Session/EntityManager is closed
at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:384)
at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:148)
at org.hibernate.internal.AbstractSharedSessionContract.checkOpenOrWaitingForAutoClose(AbstractSharedSessionContract.java:390)
at org.hibernate.internal.SessionImpl.getEntityUsingInterceptor(SessionImpl.java:563)
at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.hydrateEntityState(EntityReferenceInitializerImpl.java:188)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:102)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractRows(ResultSetProcessorImpl.java:157)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:94)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:105)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:87)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:710)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:76)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2163)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:589) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:178)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:163)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:162)
at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:168)
**at lt.json.model.DeviceJson.<init>(DeviceJson.java:61)**
... 33 more
The class raising this error is as follow (line 61)
package lt.json.model;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import org.hibernate.LazyInitializationException;
import com.google.gson.annotations.Expose;
import lt.json.LTJsonModel;
import lt.json.type.LTTypeParse;
import lt.locale.DateUtils;
import lt.model.Device;
import lt.model.DeviceGroup;
import lt.model.LTTable;
import lt.model.User;
public class DeviceJson extends lt.cm.json.model.DeviceJson<DeviceDataJson> implements LTJsonModel {
private static final long serialVersionUID = 4387177204893976858L;
@Expose
private Integer id;
@Expose
protected String customId = null;
@Expose
private Set<Integer> familyIds = null;
@Expose
private String syncTime = null;
@Expose
private Map<Integer, Set<Integer>> groupsIds = null;
@Expose
private Integer parentId = null;
@Expose
private Integer nodeModelId = null;
public DeviceJson(Device device, User user) {
id = device.getId();
name = device.getName();
customId = device.getCustomId();
if (user != null) {
type = (device.getType() != null) ? device.getType().getType() : null;
online = device.isOnline();
syncTime = DateUtils.getDateTime(device.getSynctime(), device.getDeployment());
location = LTTypeParse.getPointJson(device.getLocation());
onMap = device.isOnmap();
hasList = device.isHaslist();
nodeModelId = device.getNodeModel().getId();
if (device.getParent() != null)
parentId = device.getParent().getId();
try {
if (device.getDevicedata() != null && device.getDevicedata().size() != 0) {
data = LTJsonModel.getEntities(DeviceDataJson.class, device.getDevicedata(),
device.getDeployment());
}
} catch (LazyInitializationException e) {
data = null;
}
}
try {
if (device.getFamilies() != null && device.getFamilies().size() != 0) {
familyIds = new HashSet<>();
device.getFamilies().forEach(family -> familyIds.add(family.getId()));
}
} catch (LazyInitializationException e) {
familyIds = null;
}
try {
Map<DeviceGroup, Set<DeviceGroup>> groups = device.getGroups();
groupsIds = new HashMap<>();
for (Entry<DeviceGroup, Set<DeviceGroup>> entity : groups.entrySet()) {
Set<Integer> subGroupsIds = new HashSet<>();
for (DeviceGroup subGroup : entity.getValue())
subGroupsIds.add(subGroup.getId());
groupsIds.put(entity.getKey().getId(), subGroupsIds);
}
} catch (LazyInitializationException e) {
groupsIds = null;
}
}
@Override
public Integer getId() {
return id;
}
public String getCustomId() {
return customId;
}
public void setCustomId(String customId) {
this.customId = customId;
}
public Boolean isOnMap() {
return onMap;
}
public Boolean isHasList() {
return hasList;
}
public DeviceJson(Device device) {
this(device, null);
}
@Override
public LTTable toModel() {
Device device = new Device();
device.setId(id);
return device;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || !getClass().equals(o.getClass()))
return false;
DeviceJson device = (DeviceJson) o;
return Objects.equals(name, device.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
Here is the Entity used by this class
package lt.model;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
import org.postgresql.geometric.PGpoint;
import com.google.gson.JsonElement;
import lt.LTPlugin;
import lt.controller.CacheController.CacheTemplate;
import lt.database.LTDBConfig;
import lt.database.mapping.DeviceType;
import lt.ehcache.Heap;
import lt.ehcache.LTEhcache;
import lt.ehcache.OffHeap;
import lt.json.LTJsonModel;
import lt.json.model.DeviceJson;
import lt.websocket.ModelObj.LTEventObject;
@LTPlugin
@Entity(name = "Device")
@Table(name = "lt_device", schema = LTDBConfig.LTSchema)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NaturalIdCache
@LTEhcache(template = CacheTemplate.LONG_TIME)
public class Device extends LTTable implements LTEventObject {
private static final long serialVersionUID = 3028650185302870665L;
@ManyToOne
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "deploymentID", nullable = false, updatable = false, insertable = false)
private Deployment deployment;
@Column(name = "deploymentID", nullable = false)
private int deploymentId;
@ManyToOne
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "nodeModelId")
private NodeModel nodeModel;
@NaturalId(mutable = false)
@Column(name = "name", length = 100, nullable = false)
private String name;
@Column(name = "customID")
private String customId;
@Column(name = "online", nullable = false)
private boolean online = false;
@Column(name = "synctime", nullable = true)
private LocalDateTime synctime;
@Column(name = "onmap", nullable = false)
private boolean onmap = true;
@Column(name = "haslist", nullable = false)
private boolean haslist = false;
@ManyToOne
@Fetch(FetchMode.SELECT)
@JoinColumn(name = "bridgeID", nullable = true)
private Bridge bridge;
@Column(name = "location", nullable = false)
private PGpoint location = new PGpoint();
@ManyToOne
@Fetch(FetchMode.SELECT)
@JoinColumn(name = "parentID", nullable = true, updatable = false)
private Device parent;
@OneToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.REFRESH}, fetch = FetchType.LAZY)
@JoinColumn(name = "parentID", insertable = false, updatable = false)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@LTEhcache(template = CacheTemplate.LONG_TIME)
private Set<Device> children = new HashSet<>();
@Column(name = "deviceType", columnDefinition = LTDBConfig.LTSchema + ".lt_devicetype", nullable = true, updatable = false)
private DeviceType type;
@Column(name = "devicetypekey", length = 100, nullable = true)
private String typeKey;
@OneToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.REFRESH},
fetch = FetchType.LAZY,
mappedBy = "device", orphanRemoval = true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@LTEhcache(template = CacheTemplate.LONG_TIME_SMALL)
private Set<DgLink> groups = new HashSet<>();
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.REFRESH},
fetch = FetchType.LAZY)
@JoinTable(name = "lt_linkdevicefamily", schema = LTDBConfig.LTSchema,
joinColumns = @JoinColumn(name = "deviceID", nullable = false, updatable = false),
inverseJoinColumns = @JoinColumn(name = "familyID", nullable = false, updatable = false))
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@LTEhcache(template = CacheTemplate.LONG_TIME_SMALL)
private Set<Family> families = new HashSet<>();
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "deviceID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@LTEhcache(template = CacheTemplate.ONE_DAY, heap = @Heap(size = 10000), offHeap = @OffHeap(size = 30))
private Set<DeviceData> devicedata = new HashSet<>();
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "deviceID")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@LTEhcache(template = CacheTemplate.LONG_TIME_SMALL)
private Set<DeviceSubGroup> subGroups = new HashSet<>();
public Deployment getDeployment() {
return deployment;
}
public int getDepId() {
return deployment.getId();
}
public void setDeployment(Deployment deployment) {
this.deployment = deployment;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCustomId() {
return customId;
}
public void setCustomId(String customId) {
this.customId = customId;
}
public Bridge getBridge() {
return bridge;
}
public void setBridge(Bridge bridge) {
this.bridge = bridge;
}
public PGpoint getLocation() {
return location;
}
public void setLocation(PGpoint location) {
this.location = location;
}
public Set<Family> getFamilies() {
return families;
}
public void setFamilies(Set<Family> family) {
this.families = family;
}
public Set<DeviceData> getDevicedata() {
return devicedata;
}
public void setDevicedata(Set<DeviceData> devicedata) {
this.devicedata = devicedata;
}
public boolean isOnline() {
return online;
}
public int getDeploymentId() {
return deploymentId;
}
public void setDeploymentId(int deploymentId) {
this.deploymentId = deploymentId;
}
public void setOnline(boolean online) {
this.online = online;
}
public LocalDateTime getSynctime() {
return synctime;
}
public void setSynctime(LocalDateTime synctime) {
this.synctime = synctime;
}
public NodeModel getNodeModel() {
return nodeModel;
}
public void setNodeModel(NodeModel nodeModel) {
this.nodeModel = nodeModel;
}
public Set<DgLink> getGroupsLink() {
return groups;
}
public Device getParent() {
return parent;
}
public void setParent(Device parent) {
this.parent = parent;
}
public DeviceType getType() {
return type;
}
public void setType(DeviceType type) {
this.type = type;
}
public String getTypeKey() {
return typeKey;
}
public void setTypeKey(String typeKey) {
this.typeKey = typeKey;
}
public boolean isOnmap() {
return onmap;
}
public void setOnmap(boolean onmap) {
this.onmap = onmap;
}
public boolean isHaslist() {
return haslist;
}
public void setHaslist(boolean haslist) {
this.haslist = haslist;
}
public Set<DeviceSubGroup> getSubGroups() {
return subGroups;
}
public Set<Device> getChildren() {
return children;
}
public void setChildren(Set<Device> children) {
this.children = children;
}
public Map<DeviceGroup, Set<DgLink>> getGroupsInfo() {
Map<DeviceGroup, Set<DgLink>> groups = new HashMap<>();
for (DgLink group : this.groups) {
if(!groups.containsKey(group.getGroup())) {
Set<DgLink> subGroups = new HashSet<>();
if(!group.getGroup().equals(group.getSubGroup()))
subGroups.add(group);
groups.put(group.getGroup(),subGroups);
} else if(!group.getGroup().equals(group.getSubGroup()))
groups.get(group.getGroup()).add(group);
}
return groups;
}
public Map<DeviceGroup, Set<DeviceGroup>> getGroups() {
Map<DeviceGroup, Set<DeviceGroup>> groups = new HashMap<>();
for(Map.Entry<DeviceGroup, Set<DgLink>> entry : getGroupsInfo().entrySet())
groups.put(entry.getKey(), entry.getValue()
.stream().map(dgl -> dgl.getSubGroup()).collect(Collectors.toSet()));
return groups;
}
public void addGroups(Map<DeviceGroup, Set<DeviceGroup>> groups) {
for (Entry<DeviceGroup, Set<DeviceGroup>> entity : groups.entrySet()) {
DgLink dgLinkGroup = new DgLink(this, entity.getKey(), entity.getKey());
if(!this.groups.contains(dgLinkGroup)) {
this.groups.add(dgLinkGroup);
entity.getKey().getDevicesLink().add(dgLinkGroup);
}
if(entity.getValue() != null)
for (DeviceGroup subGroup : entity.getValue())
if(!subGroup.equals(entity.getKey())) {
DgLink dgLinkSubGroup = new DgLink(this, entity.getKey(), subGroup);
if(!this.groups.contains(dgLinkSubGroup)) {
this.groups.add(dgLinkSubGroup);
entity.getKey().getDevicesLink().add(dgLinkSubGroup);
}
}
}
}
public void removeGroups(Map<DeviceGroup, Set<DeviceGroup>> groups) {
Set<DgLink> newSubGroups = new HashSet<>();
Set<DgLink> newGroups = new HashSet<>();
Set<DgLink> delGroups = new HashSet<>();
for (Entry<DeviceGroup, Set<DeviceGroup>> entity : groups.entrySet()) {
newSubGroups.add(new DgLink(this, entity.getKey(), entity.getKey()));
if(entity.getValue() != null)
for (DeviceGroup subGroup : entity.getValue())
if(!subGroup.equals(entity.getKey()))
newSubGroups.add(new DgLink(this, entity.getKey(), subGroup));
}
for (DgLink dgLink : this.groups)
if(!newGroups.contains(dgLink)
|| !newSubGroups.contains(dgLink))
delGroups.add(dgLink);
for (DgLink dgLink : delGroups) {
this.groups.remove(dgLink);
dgLink.getGroup().getDevicesLink().remove(dgLink);
dgLink.setDevice(null);
dgLink.setGroup(null);
dgLink.setSubGroup(null);
}
}
public void addFamily(Family family) {
if(families.add(family))
family.getDevices().add(this);
}
public void removeFamily(Family family) {
if(families.remove(family))
family.getDevices().remove(this);
}
public ModelProperty getModelProperty(String tag) {
for(ModelProperty modelProperty : nodeModel.getModelProperties())
if(modelProperty.getTag().equals(tag))
return modelProperty;
return null;
}
public FamilyProperty getFamilyProperty(ModelProperty modelProperty) {
if(modelProperty == null) return null;
for(FamilyProperty familyProperty : modelProperty.getFamilyProperties())
if(families.contains(familyProperty.getFamily()))
return familyProperty;
return null;
}
public FamilyProperty getFamilyProperty(String tag) {
return getFamilyProperty(getModelProperty(tag));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || !getClass().equals(o.getClass())) return false;
Device device = (Device) o;
return Objects.equals(name, device.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public JsonElement toJson(User user) {
return LTJsonModel.toJson(DeviceJson.class, this, user);
}
}
The Set has FetchType.LAZY.
I have this error expecially when I have in the DB more than 100 devices, keep in mind that I share the Hibernate Session among threads and the DeviceData are updated quiet often.
Any help will be appreciated