How to read recursive List in java - java

I can not read a recursive list of items.
I have a tree of categories, each category has children, which in turn can have children (do not know how many).
This is my class:
public class Category {
public int HasChild = 0;
public int level;
public boolean isOpened = false;
#ElementList(entry = "Category", required = false, empty = true, data = true, inline = true)
private List<Category> childrenCategory;
#Attribute(required = false)
private String id;
#ElementList(entry = "Name", inline = true, required = false)
public List<Name> name;
public List<Category> getCategoy() {
return childrenCategory;
}
public void setCategoy(List<Category> categoy) {
childrenCategory = categoy;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Name> getName() {
return name;
}
public void setName(List<Name> name) {
this.name = name;
}
#Override
public String toString() {
return "Category [childrenCategory=" + childrenCategory + ", id=" + id
+ "]";
}
}
This is my function where a foreach control Things will:
void function(Category cat) {
for (Category iterable_element : cat.getCategoy()) {
Log.i("link", iterable_element.toString());
if (cat.getCategoy() != null) {
//
// holder.btn.setEnabled(true);
// cat.HasChild = 1;
Log.i("link", "isEmpity");
}
}
Here is where you call the function, where the oject initial step:
object = category;
function(object);
my problem is that I can control in this way Things will only top level if I would like to access those second level should do:
object = category.getCategoy().get(0);
function(object);
but this is not possible because everything has to be recursive, and not hand written.
Should I once read the first iterate the oject to the next level
help me, thanks

Call the function recursively. Here is the code.
void function(Category cat) {
if (cat.getCategoy().size() > 0) {
for (Category iterable_element : cat.getCategoy()) {
log.i("Has "+cat.getCategoy().size() + " children.");
function(iterable_element); // again call it recursively
}
}
else {
log.i("No children.");
}
}

Related

Add record in detail in master-detail ADF in two sessions

if I have a master entity :
#Entity
public class Test implements Serializable {
#Id
#Column(name="TEST_ID" nullable = false)
private BigDecimal testId;
#Column(unique = true, length = 30)
private String code;
#Temporal(TemporalType.TIMESTAMP)
#Column(nullable = false, length = 50)
private String name;
#Column(name="SYS_VERSION_NUMBER",nullable = false, length = 50)
private Long sysVersionNumber;
#OneToMany(mappedBy = "test", orphanRemoval=true, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
private List<TestDetail> testDetailList;
public Test() {}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getTestId() {
return testId;
}
public void setTestId(BigDecimal testId) {
this.testId = testId;
}
public Long getSysVersionNumber() {
return sysVersionNumber;
}
public void setSysVersionNumber(Long sysVersionNumber) {
this.sysVersionNumber = sysVersionNumber;
}
public List<TestDetail> getTestDetailList() {
return testDetailList;
}
public void setTestDetailList(List<TestDetail> testDetailList) {
this.testDetailList = testDetailList;
}
public TestDetail addTestDetailList(TestDetail testDetail) {
getTestDetailList().add(testDetail testDetail);
testDetail.setTest(this);
testDetail.setTestId(this.getTestId());
return testDetail;
}
public TestDetail removeProvbilling(TestDetail testDetail) {
getTestDetailList().remove(testDetail testDetail);
testDetail.setTest(null);
testDetail.setTestId(null);
return testDetail;
}
#Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof Test)) {
return false;
}
final Test other = (Test) object;
if (!(id == null ? other.testId == null : testId.equals(other.testId))) {
return false;
}
return true;
}
#Override
public int hashCode() {
final int PRIME = 37;
int result = 1;
result = PRIME * result + ((test == null) ? 0 : test.hashCode());
return result;
}
}
and I have a detail entity
#Entity
public class Testdetail implements Serializable {
#Id
#Column(name = "TESTDETAIL_ID", nullable = false)
private BigDecimal testdetailId;
#Version
#Column(name = "SYS_VERSION_NUMBER")
private Long sysVersionNumber;
#ManyToOne
#JoinColumn(name = "TEST_ID", insertable=false, updatable=false)
private TEST test;
#Column(name = "TEST_ID",)
private BigDecimal testId;
#Column
private String name;
public Testdetail() {
}
public Test getTest() {
return test;
}
public void setTest(Test test) {
this.test = test;
}
public void setTestId(BigDecimal testId) {
this.testId = testId;
}
public BigDecimal getTestId() {
return testId;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Long getSysVersionNumber() {
return sysVersionNumber;
}
public void setSysVersionNumber(Long sysVersionNumber) {
this.sysVersionNumber = sysVersionNumber;
}
}
if I run the page in twice two tabs with the same Test record and add new record for 'testDetail' in the first tab then add record for 'testDetail' in second tab (I am calling method mergeTest() in sessionbean which invoke em.merge(test) on saving), the added record in fist tab is gone even though sysversionnumber is working properly to prevent user from editing existing records if they were edited in the second tab.
is there a way to prevent user from adding record in second tab or to lock master record if it is used through EntityManager in sessionBean?
I found a solution after calling em.merge(test); I have to lock it using
em.lock(test, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

Filter user by Role cause a infinity recursion

Overview
I'm learning Angular Java and JHipster, and I'm trying to filter the Users by Role but im getting a infinity recursion.
this is my userRepository.java
#Query(value = "select user from User user inner join user.authorities authorities where authorities.name =:role")
List<User> findByRole(#Param("role") String role);
I trying to do a inner join between the user table and the user_authority table, im parsing the role like a String "ROLE_ADMIN"
Upadte
Found something in the model if i do this select user.login instead of select users don't get the recursion error, so I think is maybe cause in the model is calling itself several times.
I have a relationship 1:1 with a another entity called extendedUser (for save additional information) and in extendedUser i have another relationship with user called coordinator so I think the model is calling itself.
This is just a part of the recursion in the console:
2019-03-22 14:08:32.082 WARN 12044 --- [ XNIO-2 task-9] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain:["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]->com.gits.sigem.domain.ExtendedUser["usuario"]->com.gits.sigem.domain.User["extendedUser"]
And this is my DTO on extended user when i think I have the problem
/**
* A DTO for the ExtendedUser entity.
*/
public class ExtendedUserDTO extends UserDTO implements Serializable {
private final Logger log = LoggerFactory.getLogger(ExtendedUserDTO.class);
private Long id;
private String puesto;
private BigDecimal sueldo;
private LocalDate fechaIngreso;
private Long usuarioId;
//private Long coordinadorId;
private Set<Area> areas = new HashSet<>();
private Long coordinadorId;
private String coordinadorLogin;
private User coordinador;
private Set<Desarrollo> desarrollos = new HashSet<>();
public ExtendedUserDTO(){
}
public ExtendedUserDTO(User user){
super(user);
this.puesto = user.getExtendedUser().getPuesto();
this.sueldo = user.getExtendedUser().getSueldo();
this.fechaIngreso = user.getExtendedUser().getFechaIngreso();
this.id = user.getId();
this.usuarioId = user.getId();
this.coordinadorLogin = user.getExtendedUser().getCoordinador().getLogin();
this.coordinadorId = user.getExtendedUser().getCoordinador().getId();
this.coordinador = user.getExtendedUser().getCoordinador();
Hibernate.initialize(user.getExtendedUser().getAreas());
this.areas = user.getExtendedUser().getAreas();
Hibernate.initialize(user.getExtendedUser().getDesarrollos());
this.desarrollos = user.getExtendedUser().getDesarrollos();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPuesto() {
return puesto;
}
public void setPuesto(String puesto) {
this.puesto = puesto;
}
public BigDecimal getSueldo() {
return sueldo;
}
public void setSueldo(BigDecimal sueldo) {
this.sueldo = sueldo;
}
public LocalDate getFechaIngreso() {
return fechaIngreso;
}
public void setFechaIngreso(LocalDate fechaIngreso) {
this.fechaIngreso = fechaIngreso;
}
public Long getUsuarioId() {
return usuarioId;
}
public void setUsuarioId(Long userId) {
this.usuarioId = userId;
}
/* public void setCoordinadorId(Long userId) {
this.coordinadorId = userId;
}
public Long getCoordinadorId() {
return coordinadorId;
}*/
public User getCoordinador() {
return coordinador;
}
public void setCoordinador(User user) {
this.coordinador = user;
}
public Set<Area> getAreas() {
return areas;
}
public void setAreas(Set<Area> areas) {
this.areas = areas;
}
public Set<Desarrollo> getDesarrollos() {
return desarrollos;
}
public void setDesarrollos(Set<Desarrollo> desarrollos) {
this.desarrollos = desarrollos;
}
public Long getCoordinadorId() {
return coordinadorId;
}
public void setCoordinadorId(Long userId) {
this.coordinadorId = userId;
}
public String getCoordinadorLogin() {
return coordinadorLogin;
}
public void setCoordinadorLogin(String userLogin) {
this.coordinadorLogin = userLogin;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ExtendedUserDTO extendedUserDTO = (ExtendedUserDTO) o;
if (extendedUserDTO.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), extendedUserDTO.getId());
}
#Override
public int hashCode() {
return Objects.hashCode(getId());
}
#Override
public String toString() {
return "ExtendedUserDTO{" +
"id=" + getId() +
", puesto='" + getPuesto() + "'" +
", sueldo=" + getSueldo() +
", fechaIngreso='" + getFechaIngreso() + "'" +
", usuario=" + getUsuarioId() +
", coordinador='" + getCoordinadorLogin() + "'" +
"}";
}
}
Notes
I'm really new on Angular, Java, and Jhipster.
Please if I missed something important, let me know on the comment
and I will added to the question.
Im just trying to get only the ADMIN users so if you have a better
way I really would like to know

Trying to delete an object from Arraylist - still possible to access object

i'm trying to add function to delete objects from my array list (first i want to generate unique random ids for these objects:
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;
public class Medium {
public Medium(){
this.id = generateID();
System.out.println("ID: " + id);
mlist.add(this);
}
protected int generateID() {
Random random = new Random();
int id;
do {
id = 100 + (random.nextInt(999-100));
} while(idlist.contains(id));
idlist.add(id);
return id;
}
protected boolean delete(Medium delElem) {
boolean isDeleted = false;
ListIterator<Medium> it = mlist.listIterator();
while(it.hasNext()) {
it = mlist.listIterator();
Medium next = it.next();
if(delElem.getID() == next.getID()) {
delElem = next;
mlist.remove(delElem);
delElem = null;
if(delElem == null) {
System.out.println("Succesfull deleted");
}
isDeleted = true;
break;
}
}
return isDeleted;
}
protected int getID() {
return id;
}
public String getTitle() {
return title;
}
protected ArrayList<Medium> mlist = new ArrayList<Medium>();
private ArrayList<Integer> idlist = new ArrayList<Integer>();
protected String title;
protected final int id;
}
I'm not sure if i understand this properly, but if i set the delElem = the object that meets the equal id, delete my object and set it = null, the object should not reference anymore. But if I test it in my main function, for example book.getTitle(), the title will be printed. I think it's because it's just a local object in my function. How can I globally delete my object in a function and return a boolean value if the object was removed succesfully?
Thanks!
It has already been stated in the comments that you usually don't delete objects manually (by setting them to null). The garbage collection will do it's job when they are not needed anymore.
The weird thing in your code is that the medium adds itself to the list. Why don't you create another class that represents a book shelf. This way you can implement methods on the bookshelf to add or remove books:
package com.example;
import java.util.ArrayList;
import java.util.Random;
public class BookShelf {
protected ArrayList<Medium> mlist = new ArrayList<Medium>();
private ArrayList<Integer> idlist = new ArrayList<Integer>();
private class Medium {
protected int id;
protected String title;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
public Medium addMedium(String title) {
Medium medium = new Medium();
medium.setId(this.generateID());
medium.setTitle(title);
this.mlist.add(medium);
return medium;
}
protected int generateID() {
Random random = new Random();
int id;
do {
id = 100 + (random.nextInt(999 - 100));
} while (idlist.contains(id));
idlist.add(id);
return id;
}
protected boolean delete(Medium delElem) {
boolean isDeleted = false;
for (Medium medium : mlist) {
if (medium.getId() == delElem.getId()) {
mlist.remove(medium);
isDeleted = true;
break;
}
}
return isDeleted;
}
public ArrayList<Medium> getAllBooks() {
return this.mlist;
}
#Override
public String toString() {
StringBuilder strBuilder = new StringBuilder();
strBuilder.append("Books in the shelf: " + this.getAllBooks().size() + "\n");
for(Medium medium : this.getAllBooks()) {
strBuilder.append("Title: " + medium.getTitle() + "\n");
}
return strBuilder.toString();
}
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf();
//Add two books to the shelf
Medium medium1 = bookShelf.addMedium("Book 1");
Medium medium2 = bookShelf.addMedium("Book 2");
System.out.println(bookShelf.toString());
//Delete one
bookShelf.delete(medium1);
System.out.println(bookShelf.toString());
}
}

How to build class to manage the output of search index query with JSON document in cloudant

I followed the sample class Animal at https://github.com/cloudant/java-cloudant/blob/88202a1bd7b9b04d96c4b7b8498a1b8f7f99c9e5/src/test/java/com/cloudant/tests/Animal.java
I successfully managed search index query by this class. I suppose that i have a document with JSON format in cloudant as:
{
"_id": "web",
"_rev": "11-b1d0e315272a87c2549df4004d836049",
"min_weight": 40,
"max_weight": 65,
"min_length": 1,
"max_length": 2.2,
"attributeCollection": {
"attributeArray": [
{
"updateable": false,
"lookup": "issuetype",
"issueAttributeDefinitionId": 13,
"attributeType": 1,
"name": "web issue",
"value": [
"Improper Neutralization of Input During Web Page Generation"
]
}
]
},
}
My question is how to build a Java class to manage the search index output for this documents. Particularly, how to manage set of attributes as "attributeCollection", "attributeArray", ..."name", "value"
based on your last few Stack Overflow posts I think you have a couple of options:
1) If you define your issue class as you did in your previous post you can perform a different kind of search in Java to just return those fields in your issue class as follows:
SearchResult<issue> issues=db.search("attributes/by_name_value")
.limit(10).includeDocs(false)
.querySearchResult("name:\"web*\"", issue.class);
for (int i = 0; i < issues.getRows().size(); i++) {
SearchResult<issue>.SearchResultRow row = issues.getRows().get(i);
System.out.println(row.getId());
System.out.println(row.getFields().getName());
System.out.println(row.getFields().getValue());
}
Note: this calls querySearchResult instead of query and include_docs is false.
2) If you need to return the entire document then you need to create classes that match your JSON. Your classes should look something like this:
Issue2
public class Issue2 {
private String id;
private Integer min_weight;
// TODO: other fields
private AttributeCollection attributeCollection;
public Issue2() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getMin_weight() {
return min_weight;
}
public void setMin_weight(Integer min_weight) {
this.min_weight = min_weight;
}
public AttributeCollection getAttributeCollection() {
return attributeCollection;
}
public void setAttributeCollection(AttributeCollection attributeCollection) {
this.attributeCollection = attributeCollection;
}
}
AttributeCollection
public class AttributeCollection {
private Attribute[] attributeArray;
public Attribute[] getAttributeArray() {
return attributeArray;
}
public void setAttributeArray(Attribute[] attributeArray) {
this.attributeArray = attributeArray;
}
}
Attribute
public class Attribute {
private String name;
private String value[];
// TODO: other fields
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getValue() {
return value;
}
public void setValue(String[] value) {
this.value = value;
}
}
Then you can use the previous search call (with Issue2 class):
List<Issue2> issues=db.search("attributes/by_name_value")
.limit(10).includeDocs(true)
.query("name:\"web*\"", Issue2.class);
for (int i = 0; i < issues.size(); i++) {
Issue2 row = issues.get(i);
System.out.println("min_weight = " + row.getMin_weight());
if (row.getAttributeCollection() != null && row.getAttributeCollection().getAttributeArray() != null) {
for (int j=0; j<row.getAttributeCollection().getAttributeArray().length; j++) {
String name = row.getAttributeCollection().getAttributeArray()[i].getName();
String[] values = row.getAttributeCollection().getAttributeArray()[i].getValue();
System.out.println(name);
if (values != null) {
for(String value: values) {
System.out.println(value);
}
}
}
}
}

Spring RequestBody Mapping maps all attributes to null values

i have the following RESTfull method :
#RequestMapping(value = "/budgetLines",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public void create(#RequestBody BudgetLine budgetLine) {
System.out.println("Before Persisting in the repository " + budgetLine);
budgetLineRepository.save(budgetLine);
}
I'am consuming this method inside a web application, i checked using the network analysis tool (in the web developper tool of chrome) that the object sended is valid (all attribute except the id were set with a valid value), but then the object passed to the repository contains only null attributes.
here is an example body :
{
"Name":"testLabel",
"Label":"testName",
"AnnualBudget":9000
}
the class BudgetLine is defined as follows:
#Entity
#Table(name = "T_BUDGETLINE")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class BudgetLine implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "label")
private String Label;
#Column(name = "name")
private String Name;
#Column(name = "annual_budget", precision=10, scale=2)
private BigDecimal AnnualBudget;
#OneToMany(mappedBy = "budgetLine")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Report> reportss = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLabel() {
return Label;
}
public void setLabel(String Label) {
this.Label = Label;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public BigDecimal getAnnualBudget() {
return AnnualBudget;
}
public void setAnnualBudget(BigDecimal AnnualBudget) {
this.AnnualBudget = AnnualBudget;
}
public Set<Report> getReportss() {
return reportss;
}
public void setReportss(Set<Report> Reports) {
this.reportss = Reports;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BudgetLine budgetLine = (BudgetLine) o;
if (id != null ? !id.equals(budgetLine.id) : budgetLine.id != null) return false;
return true;
}
#Override
public int hashCode() {
return (int) (id ^ (id >>> 32));
}
#Override
public String toString() {
return "BudgetLine{" +
"id=" + id +
", Label='" + Label + "'" +
", Name='" + Name + "'" +
", AnnualBudget='" + AnnualBudget + "'" +
'}';
}
public BudgetLine() {
}
}
Try with first letter in lowercase for parameters
{
"name":"testLabel",
"label":"testName",
"annualBudget":9000
}
Spring relies heavily on standard Java naming conventions, so I suggest you also follow them. In your example, you should name your class fields with lowercased first letter.

Categories

Resources