Problem java Set data replaced/wiped on add - java

I have actually a problem on a Set in my project (code below)
public static Set<BeanObject> mapToSetBean(Collection<Object> listModel) {
Set<BeanObject> listToReturn = new HashSet<>();
for (Iterator<Object> iterator = listModel.iterator(); iterator.hasNext();) {
Object model = iterator.next();
BeanObject bean = new BeanObject();
bean = mapToBean(model);
listToReturn.add(bean);
}
return listToReturn;
}
When some beans are added to the list they replace another one.
For example:
List{}
add object1 / List{object1}
add object2 / List{object1, object2}
add object1 / List{object1, object2, object3}
add object4 / List{object4, object2, object3}
The equals and the hashcode of the object are override the hashcode are all different and in debug mode we don't enter in the override equals.
When I use an ArrayList everything works but I prefer not to change the type it has a huge impact on my project.
---------------- EDIT ---------------
public static BeanObject mapToBean(Object model) {
BeanObject bean = new BeanObject();
if (model != null) {
bean.setId(model.getId());
if(model.getId() != null){
bean.setIdString(model.getId().toString());
}
if (model.getName() != null) {
bean.setName(model.getName().toLowerCase());
}
bean.setActif(model.getActif());
if (model.getShortName() != null) {
bean.setShortName(model.getShortName().toUpperCase());
}
}
return bean;
}
BeanObject
public class BeanObject implements Comparable<BeanObject> {
/**
* serial
*/
private static final long serialVersionUID = 1L;
private BigInteger id;
private String name;
private String shortName;
private Short actif;
private String idString;
public BeanObject() {
}
public BeanObject(BigInteger id, String libelle) {
this.id = id;
this.name = libelle;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!(o instanceof BeanObject)) {
return false;
}
BeanObject other = (BeanObject) o;
boolean result;
if (null == this.id) {
if (null == other.id) {
result = true;
} else {
result = false;
}
} else {
result = this.id.equals(other.id);
}
return result;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
return this.id.intValue() * name.hashCode() * shortName.hashCode();
}
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public Short getActif() {
return actif;
}
public void setActif(Short actif) {
this.actif = actif;
}
public String getIdString() {
return idString;
}
public void setIdString(String idString) {
this.idString = idString;
}
}

Are you certain the BeanObject's hashcode values are unique? That hashcode method seems like it would map a lot of objects to 0 if any of its fields hashed to 0 since it is straight multiplication. I would suggest updating to a more standardized approach for it like the following:
#Override
public int hashCode() {
return Objects.hash(id, name, shortName);
}
Objects.hash is from the java.util package.
If this still doesn't solve the problem, I would double check the hashcode results for each bean object at add time.

Related

Failed to convert value of type 'java.lang.String' to required type 'ArrayList<Object>' in PostMapping

I am looking for a working use case for the following :
#PostMapping("/add-gateway")
public String addGateway(ModelMap model, #Valid Gateway gateway, BindingResult result) {
if (result.hasErrors()) {
System.out.println("GatewayController has thrown error!");
return "gateway";
}
service.addGateway(gateway.getId(), gateway.getGatewayName(), gateway.getIpAddress(), gateway.getDevices());
return "redirect:/list-gateways";
}
Here is my Gateway class:
public class Gateway {
private String id;
private String gatewayName;
private String ipAddress;
private List<Device> devices;
#NotNull(message = "Empty gateway name not allowed!")
#Size(min = 5, message = "Enter at least 5 characters!")
public Gateway() {
super();
}
public Gateway(String id, String gatewayName, String ipAddress, List<Device> exampleDevices) {
super();
this.id = id;
this.gatewayName = gatewayName;
this.ipAddress = ipAddress;
this.devices = exampleDevices;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGatewayName() {
return gatewayName;
}
public void setGatewayName(String gwName) {
this.gatewayName = gwName;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public List<Device> getDevices() {
return devices;
}
public void setDevices(ArrayList<Device> devices) {
this.devices = devices;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Integer.parseInt(id);
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Gateway other = (Gateway) obj;
if (id != other.id) {
return false;
}
return true;
}
public Map<String, List<Device>> getGatewayAndDevices(Gateway gateway) {
return (Map<String, List<Device>>) new HashMap().put(gateway.getGatewayName(), gateway.getDevices());
}
#Override
public String toString() {
return String.format("Gateway [id=%s, gatewayName=%s, ipAddress=%s, devices=%s]", id, gatewayName, ipAddress,
devices);
}
}
The program fails on the returned "gateway" String, because one of the parameters of the Gateway constructor is an ArrayList of Objects, so that I never add a new Gateway to the list of Gateways and never return "redirect:/list-gateways"... I tried lots of workarounds for parsing the ArrayList to String, or using a Converter class, or playing with the initBinder method, however none of them seems to work here...I will greatly appreciate your help, because I need a working solution until the end of tomorrow! Many thanks in advance!

Defining final variables in swagger.yaml

Is it somehow possible to define in swagger something that I get this in the Java code with the swagger-codegen project?
public final int XYZ = 2;
public final String ABC = "something_but_not_abc";
So in my case I want to change the Enums to have it with id:
something similar like:
public final int BESTOF15 = 2;
this is how the definition looks like in my swagger.yaml file.
definitions:
GameMode:
type: object
properties:
id:
type: integer
description: id of the gamemode
name:
type: string
description: name of the player
enum:
- bestOf15
- bestOf100Seconds
- bestOfDepartment
- learning
description:
type: string
description: description of the game mode
this code will look in Java, with the help of the swagger-codegen project like:
public class GameMode {
#JsonProperty("id")
private Integer id = null;
/**
* name of the player
*/
public enum NameEnum {
BESTOF15("bestOf15"),
BESTOF100SECONDS("bestOf100Seconds"),
BESTOFDEPARTMENT("bestOfDepartment"),
LEARNING("learning");
private String value;
NameEnum(String value) {
this.value = value;
}
#Override
#JsonValue
public String toString() {
return String.valueOf(value);
}
#JsonCreator
public static NameEnum fromValue(String text) {
for (NameEnum b : NameEnum.values()) {
if (String.valueOf(b.value).equals(text)) {
return b;
}
}
return null;
}
}
#JsonProperty("name")
private NameEnum name = null;
#JsonProperty("description")
private String description = null;
public GameMode id(Integer id) {
this.id = id;
return this;
}
/**
* id of the gamemode
* #return id
**/
#ApiModelProperty(value = "id of the gamemode")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public GameMode name(NameEnum name) {
this.name = name;
return this;
}
/**
* name of the player
* #return name
**/
#ApiModelProperty(value = "name of the player")
public NameEnum getName() {
return name;
}
public void setName(NameEnum name) {
this.name = name;
}
public GameMode description(String description) {
this.description = description;
return this;
}
/**
* description of the game mode
* #return description
**/
#ApiModelProperty(value = "description of the game mode")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GameMode gameMode = (GameMode) o;
return Objects.equals(this.id, gameMode.id) &&
Objects.equals(this.name, gameMode.name) &&
Objects.equals(this.description, gameMode.description);
}
#Override
public int hashCode() {
return Objects.hash(id, name, description);
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class GameMode {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" description: ").append(toIndentedString(description)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

Canteen with uniqe courses

I have a Canteen class and a Course class (and a BaseEntity). The Canteen class has a set of courses. A course is unique if the composition of name, dateOfServing and the canteen id is unique. I tried to write a test case which should throw an exception if a non-unique course is added to a canteen. But the test doesn't throw any exception at all. Which leads me to believe that I'm doing me Canteen and Course class wrong. The test in question is addDuplicatedCourseToCanteenTest. Anyone got a clue about what I'm doing wrong?
I'm new to TDD as well so any critique in that area is very welcome as well.
BaseEntity.java
#MappedSuperclass
public class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
long id;
private Date createdAt;
private Date updatedAt;
// TODO: http://stackoverflow.com/a/11174297/672009
// Using the above we wouldn't have to created a CommentRepository
// Is that a good idea?
/**
* http://www.devsniper.com/base-entity-class-in-jpa/
*/
/**
* Sets createdAt before insert
*/
#PrePersist
public void setCreationDate() {
this.setCreatedAt(new Date());
}
/**
* Sets updatedAt before update
*/
#PreUpdate
public void setChangeDate() {
this.setUpdatedAt(new Date());
}
public Date getCreatedAt() {
return createdAt;
}
protected void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
protected void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BaseEntity other = (BaseEntity) obj;
if (id != other.id)
return false;
return true;
}
}
Canteen.java
#Entity
public class Canteen extends BaseEntity {
private String name;
// TODO: https://schuchert.wikispaces.com/JPA+Tutorial+1+-+Embedded+Entity
// http://docs.oracle.com/javaee/6/api/javax/xml/registry/infomodel/PostalAddress.html
//private Address address;
//private PostalAddress postalAddress;
/**
* In honor of KISS I simply use a simple string address as a holder for the restaurants address.
* The idea is that the string will contain an address which will be valid according to google maps.
* Same goes for openingHours, phoneNumber and homepage... KISS wise.
*/
private String address;
private String openingHours; // A string which will be presented within a pre tag
// Eg. <pre>Mandag - Torsdag 10-22
// Fredag - Lørdag 10-24
// Søndag 11-20</pre>
private String contact;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Course> courses = new HashSet<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getOpeningHours() {
return openingHours;
}
public void setOpeningHours(String openingHours) {
this.openingHours = openingHours;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
public boolean addCourse(Course course)
{
return getCourses().add(course);
}
#Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Canteen other = (Canteen) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
Course.java
#Entity
public class Course extends BaseEntity {
private String name;
private Date dateOfServing;
#ManyToOne
private Canteen canteen;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDateOfServing() {
return dateOfServing;
}
public void setDateOfServing(Date dateOfServing) {
this.dateOfServing = dateOfServing;
}
public Canteen getCanteen() {
return canteen;
}
public void setCanteen(Canteen canteen) {
this.canteen = canteen;
}
#Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((canteen == null) ? 0 : canteen.hashCode());
result = prime * result
+ ((dateOfServing == null) ? 0 : dateOfServing.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Course other = (Course) obj;
if (canteen == null) {
if (other.canteen != null)
return false;
} else if (!canteen.equals(other.canteen))
return false;
if (dateOfServing == null) {
if (other.dateOfServing != null)
return false;
} else if (!dateOfServing.equals(other.dateOfServing))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
CanteenHasCoursesTest.java
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = PersistenceConfig.class)
public class CanteenHasCoursesTest {
#Autowired
private CanteenRepository canteenRepository;
private String canteenName;
private String courseName;
private Canteen canteen;
private Course course;
#Before
public void setUp() {
// Generate unique random name
canteenName = UUID.randomUUID().toString();
// Generate unique random name
courseName = UUID.randomUUID().toString();
// Create new canteen
canteen = new Canteen();
canteen.setName(canteenName);
// Create new course
course = new Course();
course.setName(courseName);
}
#Test
public void addCourseToCanteenTest() {
// Add course
canteen.addCourse(course);
// Save canteen
canteenRepository.save(canteen);
// Find it again
Canteen c = canteenRepository.findOne(canteen.getId());
// Confirm attributes are as expected
assertNotNull(c);
Set<Course> courses = c.getCourses();
Iterator<Course> it = courses.iterator();
assertTrue(it.hasNext());
Course course = it.next();
assertEquals(courseName, course.getName());
}
// TODO: expect some data violation exception
// #Test(expected = IndexOutOfBoundsException.class)
#Test
public void addDuplicatedCourseToCanteenTest() {
// Add course
canteen.addCourse(course);
// Add it again
canteen.addCourse(course);
// Save canteen
canteenRepository.save(canteen);
}
#After
public void tearDown() {
canteenRepository = null;
canteenName = null;
courseName = null;
canteen = null;
course = null;
}
}

Get Duplicates Objects from ArrayList

How can I get duplicates from an ArrayList?
public class Order {
private String portId;
private String action;
private String idType;
private String id;
private BigDecimal amount;
public String getPortId() {
return portId;
}
public void setPortId(String portId) {
this.portId = portId;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getIdType() {
return idType;
}
public void setIdType(String idType) {
this.idType = idType;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
}
My code:
List<Order> duplicateList = new ArrayList<Order>();
List<Order> nonDuplicateList = new ArrayList<Order>();
Set<Order> set = new HashSet<Order>();
for (Order order : listContainingAllOrders) {
if (!set.add(order)) {
duplicateList.add(order);
} else {
nonDuplicateList.add(order);
}
}
I want to achieve duplicateList and nonDuplicateList, where I will combine both the duplicate list and Non duplicate List together
and display on the UI. The duplicate Orders will be Identified by Error Message column.
If I understand you, then you could replace this
if (!set1.add(order)) {
with
if (!set1.contains(order)) {
set1.add(order);
Edit
You need to Override equals() and hashCode() in your Order. Assuming that Order(s) with the same id are equal by definition - one possible way would be,
#Override
public boolean equals(Object obj) {
if (obj instanceof Order) {
if (id == null) {
// return ((Order) obj).id == null;
return false; // probably best to prevent null
}
return id.equals(((Order) obj).id);
}
return false;
}
#Override
public int hashCode() {
return id.hashCode();
}

Java hashmap mapping in database

My entity class is
#Entity
public class Student_enroll implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private int level_num;
private int term;
private String student_session;
private HashMap<String,Integer>mark_value;
#OneToOne
private Student student;
public String getStudent_session() {
return student_session;
}
public void setStudent_session(String student_session) {
this.student_session = student_session;
}
public int getLevel_num() {
return level_num;
}
public void setLevel_num(int level_num) {
this.level_num = level_num;
}
public int getTerm() {
return term;
}
public void setTerm(int term) {
this.term = term;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public HashMap<String, Integer> getMark_value() {
return mark_value;
}
public void setMark_value(HashMap<String, Integer> mark_value) {
this.mark_value = mark_value;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Student_enroll)) {
return false;
}
Student_enroll other = (Student_enroll) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.domain.Student_enroll[ id=" + id + " ]";
}
}
and my controller function is
#RequestMapping(value="/add_mark",method = RequestMethod.POST)
public void add_mark(HttpServletRequest req){
HashMap<String,Integer>map=new HashMap<String,Integer>();
int level=Integer.parseInt(req.getParameter("level"));
int term=Integer.parseInt(req.getParameter("term"));
Student_enroll enroll=student_service.get_student_enroll(level, term);
List<Course>list_course=course_service.list_course(level, term);
Iterator<Course>itr=list_course.iterator();
while(itr.hasNext()){
enroll.put(itr.next().getCourse_Code(),75);
}
enroll.setMark_value(map); // Set hashmap
student_service.update_student_enroll(enroll);
}
I want to set the HashMap by using setHashmap() and want to persist the entity in database.is it an appropriate way cause when I want to persist it other attribute of entity is persisted but the hashmap attribute contains a BLOB object.
How to persist a hashmap of primitive type?
JPA supports Map persistencse using #MapKey, #MapKeyJoinColumn ... annotations
Refer to following article for details:
http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Maps

Categories

Resources