Spring Boot + Hibernate - How to maintain #Transient fields - java

I have a POJO class:
#Entity
#Table(name = "interruttori", catalog = "SMARTPARK")
public class Interruttore implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int idInterruttore;
private int numeroInterruttore;
private String nomeInterruttore;
private String descrizione;
private List<Luce> luci;
private String pinName;
private boolean remoto;
private boolean stato;
private Date dateTime;
private Set<Integer> activeSensors = new HashSet<Integer>();
//getters and setters and specifically
#Transient
public Set<Integer> getActiveSensors() {
return activeSensors;
}
public void setActiveSensors(Set<Integer> activeSensors) {
this.activeSensors = activeSensors;
}
It's #Transient because I don't want to persist the Set, i need it just as a "counter" in a Controller.
The controller part we need is:
#RequestMapping(value="/sensoristica")
public ResponseEntity<Sensoristica> findIlluminazione(#RequestParam(value="idLuce") int idLuce,
#RequestParam(value="lit") boolean lit,
#RequestParam(value="suServer") boolean suServer) {
Sensoristica sensoristica = new Sensoristica();
Luce luce = luceService.findById(idLuce);
String nomeLuce = luce.getNomeLuce();
int numeroLuce = luce.getNumeroLuce();
sensoristica.setLuce(luce);
sensoristica.setLit(lit);
sensoristicaService.saveSensoristica(sensoristica);
logger.debug("Aggiornato sensore " + numeroLuce + " ("+nomeLuce+") acceso: "+lit);
//aggiorniamo lo stato del sensore
luce.setLit(lit);
luceService.updateLuce(luce);
//qui gestisco l'interruttore
if(suServer){
int idInterruttore = luce.getInterruttore().getIdInterruttore();
Interruttore interruttore = interruttoreService.findById(idInterruttore);
Set<Integer> activeSensors = interruttore.getActiveSensors();
logger.debug("Active sensor è " +activeSensors);
if(lit){
activeSensors.add(idLuce);
logger.debug("Aggiungo id "+idLuce);
logger.debug("Active è lungo: "+activeSensors.size());
} else {
if (activeSensors.contains(idLuce)){
activeSensors.remove(idLuce);
logger.debug("Rimuovo id "+idLuce);
logger.debug("Active è lungo: "+activeSensors.size());
}
}
interruttore.setActiveSensors(activeSensors);
interruttoreService.updateInterruttore(interruttore);
boolean canShutDown = activeSensors.isEmpty();
logger.debug("canShutDown is "+canShutDown);
Basically, I want to add or remove idLuceto the Set and then check if activeSensors.isEmpty().
The problem is that every call to the Controller gives me back an empty Set, not a Set with the previous idLuces inside.
How can I obtain it?

Actually #Transient should be applied according to AccessType.
Please try setting #Transient to the field.
#Transient
private Set<Integer> activeSensors = new HashSet<Integer>();

Related

Gson is not ignoring said #Expose annotations [duplicate]

This question already has answers here:
Serialize object using GSON
(2 answers)
Closed 3 years ago.
Code:
public class Crate {
private final MapPosition cratePosition;
private final int tierId;
#Expose(serialize = false, deserialize = false)
private final Inventory inventory;
public Crate(MapPosition cratePosition, int tierId) {
this.cratePosition = cratePosition;
this.tierId = tierId;
this.inventory = Bukkit.createInventory(null, 9*3, "Supply Crate");
}
public void replenishCrates(CrateConfig config) {
List<CrateContent> contents = config.getContentByTier(tierId);
//TODO:
}
public Inventory getInventory() {
return inventory;
}
public Location toLocation(World world) {
return cratePosition.toLocation(world);
}
public MapPosition getCratePosition() {
return cratePosition;
}
public int getTierId() {
return tierId;
}}
The #Expose is being ignored and returning a null pointer exception when trying to deserialize and serialize the class contents. I have made sure to also include the correct GsonBuilder modifications, as stated in Gson's documentation.
The problem you are having is not because #Expose is being ignored but rather because #Expose is missing on the other attributes.
The GsonBuilder's modification you are refering to is the following:
This annotation has no effect unless you build Gson with a GsonBuilder and invoke GsonBuilder.excludeFieldsWithoutExposeAnnotation() method.
But thank God the authors have correctly named the method and it will do just what it is expressing: it will exclude every field that is not marked with the #Expose annotation.
Here is an illustration based on your code (a little bit different because you did not share a completely reproductible sample)
public class Crate {
private final String cratePosition;
private final int tierId;
#Expose(serialize = false, deserialize = false)
private final Inventory inventory;
public Crate(String cratePosition, int tierId) {
this.cratePosition = cratePosition;
this.tierId = tierId;
this.inventory = new Inventory("IV-ID-111000", 10200);
}
public Inventory getInventory() {
return inventory;
}
public int getTierId() {
return tierId;
}
public String getCratePosition() {
return cratePosition;
}
}
And the following test:
public static void main(String[] args) {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Crate crate = new Crate("484:125.52", 1250);
String jsonString = gson.toJson(crate);
System.out.println(jsonString);
String json = "{\"cratePosition\":\"4894:125.52\",\"tierId\":2350}";
Crate deserialized = gson.fromJson(json, Crate.class);
System.out.println(deserialized.getCratePosition() + ":" + deserialized.getTierId());
}
In the current case I have no #Expose annotation on cratePosition and tierId fields, so they are excluded from the serialization and deserialization. Therefore my test returns:
{}
null:0
Now let's add the #Expose annotation on the cratePosition and tierId fields in the Crate class:
#Expose()
private final String cratePosition;
#Expose()
private final int tierId;
By default the serialize and deserialize parameters of the #Expose annotation are both set to true. You can play with it and change the values to see the differences it produces.
If I run the test again I have:
{"cratePosition":"484:125.52","tierId":1250}
4894:125.52:2350

IllegalArgumentException spring boot and hibernate

I have class same this:
public class DoctorCalender {
private Long reservationId;
private Date reservationDate;
private String hospitalName;
private String roomName;
private Long capacityId;
private List<Shift> shifts = new ArrayList<>();
. . .
public List<Shift> getShifts() {
return shifts;
}
public void setShifts(List<Shift> shifts) {
this.shifts = shifts;
}
}
and I'm going to hql export mapping to above class with use this method:
.setResultTransformer(Transformers.aliasToBean(DoctorCalender.class))
and I get this error :
IllegalArgumentException occurred while calling setter for property [ir.sayar.hospital.toolBox.helperClass.DoctorCalender.shifts (expected type = java.util.List)]

Persisting this object doesn't persist its parameters

Here are my entities ForfaitGenerique and Offre . Those two entities are in persistence.xml (didn't put all the methods here, if needed I will add more information):
#Entity
public class ForfaitGenerique implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int idForfait;
#NotNull
private String description = "description";
#NotNull
#OneToMany(cascade = {CascadeType.ALL},fetch = FetchType.LAZY,mappedBy = "forfaitGenerique")
private List<Offre> listeOffre;
#NotNull
#ElementCollection
List<Integer> listeRemontees;
//erreur sur mon intellij mais pas d'erreur en faisant mvn clean install.On verra au test
public ForfaitGenerique() {
}
public void addOffre(Offre o) {
this.listeOffre.add(o);
}
[...]
#Entity
public class Offre implements Serializable {
#NotNull
private AgeEnum age;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#NotNull
private double nbJour;
#Enumerated(EnumType.STRING)
#NotNull
private SaisonEnum saison;
#Enumerated(EnumType.STRING)
#NotNull
private ReductionEnum reduction;
boolean consecutif;
#NotNull
private double prix;
#ManyToOne
private ForfaitGenerique forfaitGenerique;
public Offre() {
}
Here is what I am trying to persist a ForfaitGenerique ; when I persist it and then try to retrieve it through its id (which isn't null and seems to have a good value), I get a ForfaitGenerique, which is not null, but ALL stuff it should contain is null (not the id though) :
#EJB(name="databaseAccess") protected ForfaitsInterface databaseAccess;
private ForfaitGenerique f;
private Offre offre_f;
[...]
ArrayList<Integer> l = new ArrayList<>();
l.add(1);
l.add(2);
l.add(3);
ForfaitGenerique forf = new ForfaitGenerique();
List<Offre> l_o = new ArrayList<Offre>();
forf.setListeOffre(l_o);
forf.setListeRemontees(l);
Offre o = new Offre(forf,AgeEnum.ADULTE,0.5,SaisonEnum.HAUTE,ReductionEnum.FIDELICIME,true,12.0);
forf.addOffre(o);
databaseAccess.addForfaitGenerique(forf);
int id_f = forf.getIdForfait();
assertNotNull(id_f);
System.out.println("bloublou"+id_f);
f = databaseAccess.getForfaitGenerique(id_f);
assertNotNull(f);
assertNotNull(f.getListeRemontees());//null !!
assertNotNull(f.getListeOffre());//null !!
assertEquals(f,forf);
offre_f = f.getListeOffre().get(0);
The databaseAccess object contains an entitymanager and two methods (among other), which are :
#Stateless(name="databaseAccess")
public class Forfaits implements ForfaitsInterface {
#PersistenceContext private EntityManager entityManager;
public void addForfaitGenerique(ForfaitGenerique forfaitGenerique) {
entityManager.persist(forfaitGenerique);
System.out.println("contains = "+entityManager.contains(forfaitGenerique));
}
#Override
public void addOffre(Offre o) {
entityManager.persist(o);
}
public ForfaitGenerique getForfaitGenerique(int id_forfait) {
ForfaitGenerique f = entityManager.find(ForfaitGenerique.class,id_forfait);//database.getForfaitFromId(id_forfait);
return f;
}
I think that my problem is when I am trying to persist my object, but not sure . Any help is appreciated .
In fact I just forgot to add the #Transactional(TransactionMode.COMMIT) before my test . That was the dumb solution.

Dont include Ebeans Variable in SQL Statements

I have an Ebeans Entity class which looks like this:
#Entity
public class User {
#Id
private Long userid;
#Constraints.Required
private String username;
private boolean active;
private String img;
private String status;
private int value;
private int gender; // 0 = female, 1 = male
private int orientation; // 0 = straight, 1 = gay, 2 = bi
private int listIndex; // used to store listindex for page references
private int precessor; // used to link the pages
private int sucessor;
private static final int USER_AMOUNT = 50;
/* FINDER */
public static Model.Finder<Long,User> find = new Model.Finder<Long, User>(
Long.class, User.class
);
the listIndex precessor and sucessor variables are needed in the object, but do not exist in the database. The Finder believes they are, which makes my SQL Statements fail.
So my question is can I somehow tell the Finder NOT to include this three variables in the SQL statments?
Use #Transient annotation on fields you don't want to persist, like
#Transient
private int listIndex;

GeoSpatial Radius Search Using Objectify

I am developing an application using GeoModel. I need to perform search in a particular radius based on the given latitude and longitude. I am able to generate the GeoCells in the datastore using Objectify, but not able to get back the results in a particular radius.
I am sharing my code below.
Entity Class
#Entity
public class NewsFeed implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Index
private Long feedID;
#Index
private String topic;
#Index
private String title;
private String description;
#Index
private Date createDate;
private String imageOrVideo;
private String imageUrl;
private String blobKey;
#Latitude
private Double latitude;
#Longitude
private Double longitude;
#Geocells
private List<String> cells;
// getter and setters ...
}
Custom GeocellQueryEngine Class From This Source
public class ObjectifyGeocellQueryEngine implements GeocellQueryEngine {
private String geocellsProperty;
private Objectify ofy;
public static final String DEFAULT_GEOCELLS_PROPERTY = "cells";
public ObjectifyGeocellQueryEngine(Objectify ofy) {
this(ofy, DEFAULT_GEOCELLS_PROPERTY);
}
public ObjectifyGeocellQueryEngine(Objectify ofy, String geocellsProperty) {
this.ofy = ofy;
this.geocellsProperty = geocellsProperty;
}
#Override
public <T> List<T> query(GeocellQuery baseQuery, List<String> geocells, Class<T> entityClass) {
StringTokenizer st;
int tokenNo = 0;
Query<T> query = ofy.query(entityClass);
if (baseQuery != null) {
st = new StringTokenizer(baseQuery.getBaseQuery(), ",");
while (st.hasMoreTokens()) {
query.filter(st.nextToken(), baseQuery.getParameters().get(tokenNo++));
}
}
return query.filter(geocellsProperty + " IN", geocells).list();
}
}
Fetching Data Here
Point p = new Point(24.8993714, 79.5839124);
// Generates the list of GeoCells
List<String> cells = GeocellManager.generateGeoCell(p);
List<Object> params = new ArrayList<Object>();
params.add("Movies");
GeocellQuery baseQuery = new GeocellQuery("topic == topic", "String topic",params);
ObjectifyGeocellQueryEngine objectifyGeocellQueryEngine = new ObjectifyGeocellQueryEngine(ofy(), "cells");
List<NewsFeed> list = objectifyGeocellQueryEngine.query(baseQuery, cells, NewsFeed.class);
List<NewsFeed> list2 = GeocellManager.proximitySearch(p, 10, 10000,NewsFeed.class, baseQuery, objectifyGeocellQueryEngine, GeocellManager.MAX_GEOCELL_RESOLUTION);
System.out.println(list+" : "+list2);
Now the problem is I am not getting any results out from here. Can you people please help me with this as I am not getting any exception, just getting the empty list.
I have done a workaround for this situation I have added a parallel JDO Class to store and retrieve the geospatial results.

Categories

Resources