I received a ConcurrentNodificationException when I implemented a rich:tree with dynamic loading of the nodes.
I'm using JSF1.2, Tomcat 6.0, RichFaces 3.3.3, and Java 6u31.
in JSF page I have this rich tree component
<rich:tree id="treeAreas" value="#{areaArmazenamento.treeAreas}"
var="node"
adviseNodeOpened="#{storageArea.adviseNodeOpenedTreeAreas}"
adviseNodeSelected="#{storageArea.adviseNodeSelectedTreeAreas}"
ajaxSubmitSelection="true"
componentState="#{storageArea.treeAreasState}"
nodeSelectListener="#{storageArea.selectNodeArea}"
nodeFace="#{node.type}" similarityGroupingId="true"
ondragstart="hideContextMenu();" disableKeyboardNavigation="true"
rightClickSelection="true" toggleOnClick="true" requestDelay="150"
changeExpandListener="#{storageArea.expandNodeListener}">
In Managed Bean storageArea I'have the code that load nodes, and on first time the method is called the first level of nodes is loaded, when a click in a node the substructure of this node is loaded.
On load the first level is validated the user's permissions, and this validation use the iterator of list that stores the tree nodes, this validation remove nodes that the user access is denied. some like this:
List<AreaArmazenamento> areas = root.getPastas();
synchronized (areas) {
Iterator<AreaArmazenamento> it = areas.iterator();
while(it.hasNext())
{
area = it.next();
boolean havePermission = ControllerPermission.havePermission(null, area, Permissions.VIEW, false);
if(!havePermission)
{
it.remove();
}
}
}
When I click on any node, I select the sub nodes of database and add the substructure in selected node, this working but sometimes on select node is throwed a ConcurrentNodificationException on Hashtable which is in TreeDataModule of Rich Tree.
This is a trace of exception:
Caused by: java.util.ConcurrentModificationException
at java.util.Hashtable$Enumerator.next(Hashtable.java:1031)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:136)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:154)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:154)
at org.richfaces.model.TreeDataModel.walk(TreeDataModel.java:178)
at org.richfaces.component.UITree.walk(UITree.java:422)
at org.richfaces.renderkit.TreeRendererBase.writeContent(TreeRendererBase.java:683)
anything about it may be causing this error? and why?
I Found the problem...
while(it.hasNext())
{
area = it.next();
boolean havePermission = ControllerPermission.havePermission(null, area, Permissions.VIEW, false);
if(!havePermission)
{
it.remove(); //problem here
}
}
I was removing items from the list on iteration...
Have you tried using a4j:queue ?
Related
I am working on one old application which is developed in JSF. In that, there is first page on which user fills details and clicks on next button. One filled values, it displays values on second page.
Here one bean is created who is holding first page values and it's request scoped. The page having bean of session scoped. I'm trying to access it using below code:
try {
if (obj == null) {
Application application = FacesContext.getCurrentInstance().getApplication();
appReqDetails = (ClassName) application.createValueBinding("#{obj}")
.getValue(FacesContext.getCurrentInstance());
}
} catch (Exception e) {
logger.error("Error/Exception occured:", e);
}
But approx. out of 100 users, 2-3 users are facing issue of values are not populating.
How to resolve this? Can I change scope of obj? Or any other way to get request scoped object into session scoped class?
I have a managed bean as my View in which I have a method called List<ArrayList> getImages() where I query the database and get a List of entities which is returned by the method. All well and good.
My problem is that when I try to iterate over this List from with JSF using either <c:forEach or ui:repeat e.g. <c:forEach var="image" items="#{viewBean.images}"> the server, Tomee throws and exception java.lang.UnsupportedOperationException: Result lists are read-only. and I'm not even doing anything with the values at this point.
If I just return the ArrayList with simple objects, no problem. I understand it must be something to do with the fact the object is an entity therefore tied to the database but I'm not sure the correct way, or best practice, to return the what I need to the JSP page.
Thanks.
Jason.
Edit. Below is method used for retrieving objects from db for iteration in JSF.
public List<ProfileImage> getProfileImageList() {
profileImageList = facade.findAllByProfileId(1L);
while (profileImageList.size() < 4) {
// Add placeholders to bring the list size to 4
ProfileImage placeHolder = new ProfileImage();
placeHolder.setProfileId(1L);
profileImageList.add(placeHolder);
}
return Collections.unmodifiableList(profileImageList);
}
JSF snippet below : Note, I am not doing anything with the value of var for now
<ui:repeat value="${imageUploadView.profileImageList}" var="profileImage">
<p:commandButton id="imageBtn_1" value="Picture 1" type="button" />
<p:overlayPanel id="imagePanel_1" for="imageBtn_1" hideEffect="fade" >
<ui:include src="/WEB-INF/xhtml/includes/profile_imageupload.xhtml" />
</p:overlayPanel>
</ui:repeat>
The following error is generated
javax.el.ELException: Error reading 'profileImageList' on type com.goobang.view.ImageUploadView
viewId=/profile/create_profile.xhtml
location=/Users/xxxxxxxxx/Documents/NetBeansProjects/testmaven/target/testmaven-1.0-SNAPSHOT/profile/create_profile.xhtml
phaseId=RENDER_RESPONSE(6)
Caused by:
java.lang.UnsupportedOperationException - Result lists are read-only.
at org.apache.openjpa.lib.rop.AbstractResultList.readOnly(AbstractResultList.java:44)
/profile/create_profile.xhtml at line 16 and column 87 value="${imageUploadView.profileImageList}"
I have solved it. The exception is thrown because I am modifying the list after assigning it to the result set. If I simply return the result set all is fine. So to achieve what I intended in getProfileImageList() I created a new ArrayList from the original, as suggested by tt_emrah, and then modify that before returning it.
public List<ProfileImage> getProfileImageList() {
profileImageList = new ArrayList(facade.findAllByProfileId(1L));
while (profileImageList.size() < 4) { // Add placeholders to bring the list size to 4
ProfileImage placeHolder = new ProfileImage();
placeHolder.setProfileId(1L);
profileImageList.add(placeHolder);
}
return profileImageList;
}
i got error in my codes like this :
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: Syntax error: Encountered ":" at line 1, column 42. Error Code: -1 Call: select userLevelId from USERS where id = :id Query: DataReadQuery(sql="select userLevelId from USERS where id = :id ")
and my code :
public String cek() { if (tmp.equals(tmp2)) {
y =1;
level = getItems().toString(); }
.....
.....
}
public List<Users> getItems() {
if (y.equals(1)) {
y=0;
tmp = tmp.trim();
return em.createNativeQuery("select userLevelId from USERS where id = :id")
.setParameter("id", tmp).getResultList(); }
}
so where's my fault ?
can anyone help me ?
thx b4
Main Problem
Native queries don't use named parameter syntax (:id). Use prepared statement syntax with the ?. Then use. setParameter( indexOf?, value ) . For example
...("select userLevelId from USERS where id = ?")
...setParameter(1, tmp)
Other Notes
Don't do your querying in the getter if the getter is part of the property binding. For instance if you have List<User> items as a bean property, don't do any business logic or in your case querying in the getter. The getter may be called for a few number of reason, apart from what you expect. Instead you can initialize it in a #PostConstruct method or in your constructor. If you need to update the list, have a listener method that will update it, and directly call that method
A common practice is to separate the business layer and web layer (the managed bean). The business layer can be an EJB in which you inject into the managed bean
I have implemented List.cshtml to provide a custom display for an image gallery. This is the first time I have tried to override a Projection with a Template and at first it seemed to work fine. Then I noticed that when I try to access the Projection on the backend Orchard 1.7 falls over with:
RuntimeBinderException 'Orchard.ContentManagement.ContentItem' does
not contain a definition for 'TagsPart'
Here is some code from the template List.cshtml:
List<TagRecord> uniqueTags = new List<TagRecord>();
List<dynamic> items = Model.Items;
if (items != null && items.Any())
{
foreach (var item in items)
{
if (item != null && item.ContentItem != null)
{
TagsPart part = item.ContentItem.TagsPart;
if (part != null && part.CurrentTags != null)
{
foreach (var t in part.CurrentTags)
{
if (!uniqueTags.Contains(t))
{
uniqueTags.Add(t);
}
}
}
}
}
I am ignorant on a couple of points, which I suspect may be causing the error:
How to specify a template for a Projection (more specific than 'List.cshtml'). Can I use Placement.info? How?
How should I test for the presence of a specific part in the ContentItem? Just assigning TagsPart part = item.ContentItem.TagsPart; throws the exception above.
UPDATE: I had implemented this as a Module; that is, the List.cshtml was in the Views folder of a simple Module. If I move List.cshtml to the Theme then the problem goes away. However, I would still prefer to use a module so that the layout is independent of the theme.
Orchard 1.7 includes a new query layout provider called 'Shape'. I simply used this provider, gave it a Shape Type of 'LightboxIsotope', and created a view called 'LightboxIsotope.cshtml'.
In a projection you can customize the html rendered for each property on the List. In order to acomplish this you need to go to your query, and add a new Layout, choose the properties you need, and set everything you want.
If the layouts provided in the Queries Module donĀ“t fullfill your requirements, you can allways create your own layout provider, this blog post shows an example:
http://www.stevetaylor.me.uk/image-carousel-using-twitter-bootstrap-and-orchard-cms-projections
Am using PrimeFaces 3.5 and a Tree Table in single select mode. The single node selection is working fine in the following situation:
1- user clicks on different nodes (there is only one node selected at any time)
2- user clicks on different nodes with Ctrl key down (there is only one node selected at any time)
both 1 and 2 from above are working correctly, except when the user uses the keyboard shift key. Even though the selection mode is single, the user is managing to select multiple nodes using the shift key, this causes an error because my back bean selection method is expecting one TreeNode and not TreeNode[] array.
Any idea how can I disable the shift key on this tree table?
<p:treeTable value="#{bean.obj.root}" var="somthing" id="myTreeTable"
selectionMode="single" selection="#{bean.selectedNode}">
</p:treeTable>
Thanks,
I found the problem and fixed it. The problem is in Primefaces 3.5 source code. inside the tree table onRowClick event, the shift key was handled correctly but right underneath there was a wrong if statement that triggered the re selection of the nodes. here is the right code that fix this problem:
The problem:
if(this.isMultipleSelection && shiftKey)
The fix
if(this.isMultipleSelection() && shiftKey)
It was comparing the existing of a function and not the return value of the function.
onRowClick : function(event, node) {
if($(event.target).is('td,span:not(.ui-c)')) {
var selected = node.hasClass('ui-state-highlight'),
metaKey = event.metaKey||event.ctrlKey,
shiftKey = event.shiftKey;
if(this.isCheckboxSelection()) {
this.toggleCheckboxNode(node);
}
else {
if(selected && metaKey) {
this.unselectNode(node);
}
else {
if(this.isSingleSelection()||(this.isMultipleSelection() && !metaKey)) {
this.unselectAllNodes();
}
if(this.isMultipleSelection() && shiftKey) {
this.selectNodesInRange(node);
}
else {
this.selectNode(node);
this.cursorNode = node;
}
}
}
PrimeFaces.clearSelection();
}
};