I would like to create static final instances in my application that I can use to drive logic. An example of this would be:
public class ChargeStatusType {
private String code;
private String value;
private ChargeStatusType(String code, String value){
this.code = code;
this.value = value;
}
public static final ChargeStatusType APPROVED = new ChargeStatusType("APPROVED", "Approved");
public static final ChargeStatusType COMPELTED = new ChargeStatusType("COMPLETED", "Completed");
public static final ChargeStatusType CANCELLED = new ChargeStatusType("CANCELLED", "Cancelled");
public static final ChargeStatusType FAILED = new ChargeStatusType("FAILED", "Failed");
}
which is then used in
#Entity
#Table(name="charge_result")
public class ChargeResult extends RepresentationModel<ChargeResult> {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
private ChargeStatusType chargeStatusType;
I am having issues saving ChargeResult as Spring / Hibernate does not know what to do with ChargeResult.ChargeStatusType.
Besides converting ChargeStatusType to an enum, is there a way to persist ChargeResult with a ChargeStatusType?
Instead of declaring chargeStatusType as a type of ChargeStatusType you can declare it as a String and persist that String then get the value using a static map like so
#Entity
#Table(name="charge_result")
public class ChargeResult extends RepresentationModel<ChargeResult> {
private static final Map<String, String> chargeStatusType;
static{
chargeStatusType = new HashMap<>();
chargeStatusType.put("APPROVED", "Approved");
chargeStatusType.put("COMPLETED", "Completed");
chargeStatusType.put("CANCELLED", "Cancelled");
chargeStatusType.put("FAILED", "Failed");
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
#Column
private String chargeStatusKey;
public String getChargeStatusKey(){
return chargeStatusType.get(chargeStatusKey);
}
Related
I'm trying to build a query which returns a list of generic objects.
It's my base object:
#Getter
#Setter
#EqualsAndHashCode(of = {"id"})
public class Normalized {
public static final String J_ID = "id";
public static final String J_CREATED_AT = "createdAt";
public static final String J_UPDATED_AT = "udpatedAt";
#Id
#Indexed
#JsonProperty(J_ID)
private String id;
#JsonProperty(J_CREATED_AT)
private Instant createdAt;
#JsonProperty(J_UPDATED_AT)
private Instant updatedAt;
}
It's my domain object:
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode(callSuper = true)
#JsonInclude(JsonInclude.Include.NON_NULL)
#Document
public class NormalizedContent<E extends OriginalContent> extends Normalized {
public static final String J_SOURCE = "source";
public static final String J_EXTERNAL_URL = "externalUrl";
public static final String J_MAIN_TEXT = "mainText";
public static final String J_ORIGINAL_CONTENT = "originalContent";
public static final String J_CREATED_DATE = "createdDate";
#Indexed
#JsonProperty(J_SOURCE)
private Sources source;
#Indexed
#JsonProperty(J_CREATED_DATE)
private Instant createdDate;
#JsonProperty(J_EXTERNAL_URL)
private String externalUrl;
#JsonProperty(J_MAIN_TEXT)
private String mainText;
#JsonProperty(J_ORIGINAL_CONTENT)
private E originalContent;
}
And it's a simplification of my function:
public Page<NormalizedContent<? extends OriginalContent>> findAllByQueriesAndFilters(
List<String> queriesId, Pageable pageable) {
if (queriesId == null || queriesId.isEmpty()) {
throw new IllegalArgumentException("Queries unspecified");
}
Criteria criteria = Criteria.where(NormalizedContent.J_QUERY).in(queriesId);
Query query = new Query(criteria);
query.with(pageable);
List<NormalizedContent<? extends OriginalContent>> content =
mongoTemplate.find(query, NormalizedContent.class);
Long total = mongoTemplate.count(query, OTBUserpanelUser.class);
return new PageImpl<NormalizedContent<? extends OriginalContent>>(content, pageable, total);
}
The problem is in the line:
List<NormalizedContent<? extends OriginalContent>> content =
mongoTemplate.find(query, NormalizedContent.class);
Because the content variable is a list of NormalizedContent<? extends OriginalContent> and the find method returns a list of NormalizedContent.
What can I do in order that the find method returns a list of NormalizedContent<? extends OriginalContent>?
List<NormalizedContent> content =
mongoTemplate.find(query, NormalizedContent.class);
While retiring NormalizedContent from content, cast to thethe property which hold the <? extends OriginalContent> type.
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.
I have a strange behavior. I have an entity which uses #Embeddables to store a type information (TerminalType). This types should have only fixed values. Therefore I created constants like CLIENT, BROWSER, EXTRENAL.
#Embeddable
#Audited
public class TerminalType extends DomainValue {
private static final long serialVersionUID = 1L;
public static final TerminalType CLIENT = new TerminalType("CLIENT");
public static final TerminalType BROWSER = new TerminalType("BROWSER");
public static final TerminalType EXTERNAL = new TerminalType("EXTERNAL");
protected TerminalType() {
}
protected TerminalType(String id) {
this.value = id;
}
#Column(name = "VALUE")
private String value;
/* only getter for the value ... */
}
This class is then used in an entity Terminal
#Entity
#Audited
public class Terminal {
private static final long serialVersionUID = 1L;
#Id
protected String terminalName;
#NotNull
#Embedded
#AttributeOverride(name = "value", column = #Column(name = "TERMINAL_TYPE"))
protected TerminalType type;
protected Terminal() {
}
/* setter and getter ... */
}
The problem is that the values constants sometimes change. The application can run for hours, but after a while the constant CLIENT has the value "BROWSER".
I do not have any idea what/who changes the constant? Any idea will help!
Thanks!
I have a CrudRepository that is supposed to make a query with an array (findByIn). In my repository tests it works, but when I try to use the query in my service, it doesn't work. Could someone explain why it doesn't work? Here is my setup (excluding some code irrelevant to the question)
Database model:
#Entity
#Table(name="Place")
public class Place implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "placeId", nullable = false)
private Long placeId;
#Column(name = "owner", nullable = false)
private String owner;
public Long getPlaceId() {
return placeId;
}
public void setPlaceId(Long placeId) {
this.placeId = placeId;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
}
Repository:
#Repository
public interface PlaceRepository extends CrudRepository<Place, Long> {
List<Place> findByPlaceIdIn(Long[] placeId);
}
Service (this is the part not working):
#Service
public class PlaceService {
#Autowired
private PlaceRepository placeRepository;
public List<Place> getPlaces(Long[] placeIds) {
return placeRepository.findByPlaceIdIn(placeIds);
}
}
The problem is that in my service placeRepository.findByPlaceIdIn(placeIds) returns 0 objects if placeIds contains more than one item. If placeIds contains just one item, the query works fine. I tried replacing return placeRepository.findByPlaceIdIn(placeIds) with this piece of code that does the query for every array item one by one (this actually works, but I'd like to get the query work as it should):
ArrayList<Place> places = new ArrayList<Place>();
for (Long placeId : placeIds) {
Long[] id = {placeId};
places.addAll(placeRepository.findByPlaceIdIn(id));
}
return places;
I know that the repository should work, because I have a working test for it:
public class PlaceRepositoryTest {
#Autowired
private PlaceRepository repository;
private static Place place;
private static Place place2;
private static Place otherUsersPlace;
#Test
public void testPlacesfindByPlaceIdIn() {
place = new Place();
place.setOwner(USER_ID);
place2 = new Place();
place2.setOwner(USER_ID);
place = repository.save(place);
place2 = repository.save(place2);
Long[] ids = {place.getPlaceId(), place2.getPlaceId()};
assertEquals(repository.findByPlaceIdIn(ids).size(), 2);
}
}
I also have another repository for other model, which also uses findByIn and it works fine. I can't see any relevant difference between the repositories. I thought it might offer some more details to show the working repository, so I included it below:
Database model:
#Entity
#Table(name="LocalDatabaseRow")
#JsonIgnoreProperties(ignoreUnknown=false)
public class LocalDatabaseRow implements Serializable {
public LocalDatabaseRow() {}
public LocalDatabaseRow(RowType rowType) {
this.rowType = rowType;
}
public enum RowType {
TYPE1,
TYPE2
};
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
#JsonProperty("id")
private Long id;
#JsonProperty("rowType")
#Column(name = "rowType")
private RowType rowType;
public Long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public RowType getRowType() {
return rowType;
}
public void setRowType(RowType rowType) {
this.rowType = rowType;
}
}
Repository:
#Repository
public interface LocalDatabaseRowRepository extends CrudRepository<LocalDatabaseRow, Long> {
List<LocalDatabaseRow> findByRowTypeAndUserIdIn(RowType type, String[] userId);
}
try using a list instead :
findByPlaceIdIn(List placeIdList);
You have a typo in your code (the repository declaration in the service):
#Autowired
private placeRepository placeRepository;
Should be:
#Autowired
private PlaceRepository placeRepository;
I have this Play Model class that I'm trying to modify an object of, and when I want to save it, I get the following exception:
java.lang.RuntimeException: No #javax.persistence.Id field found in class [class models.Contact]
at play.db.ebean.Model._idAccessors(Model.java:39)
at play.db.ebean.Model._getId(Model.java:52)
The class:
#Entity
public class Contact extends Model implements Person {//, Comparable<Contact>{
private Long id;
private Client client;
#Required
private String email;
private String profil_picture;
private Boolean active = new Boolean(true);
private Boolean favorite = new Boolean(false);
#Transient
private Boolean profile_pic_url_init = new Boolean(false);
#Id
#GeneratedValue
public Long getId() {
return id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="client_id")
public Client getClient(){
return client;
}
public void setClient(Client client){
this.client= client;
}
#Column
public Boolean getFavorite() {
return favorite;
}
public void setFavorite(Boolean is_favorite) {
this.favorite = is_favorite;
}
....
}
The code calling the save() method:
List<Contact> contacts_list = current_client.getContacts();
for (Contact c : contacts_list) {
c.setFavorite(false);
c.save();
}
The class actually has an #Id annotation, so any guesses of why this doesn't work? I tried looking it up on google, but couldn't find much about this error. Thanks in advance!
Move #Id annotation to id field instead of its getter.