Using user id with other model classes - java

I am using the play-authenticate plugin in my play-framework project. I want to be able to use the user ID (of the user currently logged in) from the User.java model class of the plugin.
#Id
public Long id;
I want to do this so that when users are creating entries in a separate model class I can store the user who has created these entries. Is there functionality in place to access this information or would I need to write an additional method in the User class to return the active user?
package controllers;
import java.text.SimpleDateFormat;
import java.util.Date;
import models.*;
import models.User;
import play.Routes;
import play.data.Form;
import play.mvc.*;
import play.mvc.Http.Response;
import play.mvc.Http.Session;
import providers.MyUsernamePasswordAuthProvider;
import providers.MyUsernamePasswordAuthProvider.MyLogin;
import providers.MyUsernamePasswordAuthProvider.MySignup;
import play.data.*;
import views.html.*;
import play.*;
import be.objectify.deadbolt.actions.Restrict;
import com.feth.play.module.pa.PlayAuthenticate;
import com.feth.play.module.pa.providers.password.UsernamePasswordAuthProvider;
public class Application extends Controller {
/*Part of the Play-Authenticate authentication plugin for the Play Framework.*/
public static final String FLASH_MESSAGE_KEY = "message";
public static final String FLASH_ERROR_KEY = "error";
public static final String USER_ROLE = "user";
public static User getLocalUser(final Session session) {
final User localUser = User.findByAuthUserIdentity(PlayAuthenticate
.getUser(session));
return localUser;
}
/*Source: https://github.com/joscha/play-authenticate*/
#Restrict(Application.USER_ROLE)
public static Result restricted() {
final User localUser = getLocalUser(session());
return ok(journeyManagement.render(localUser));
}
/*Source: https://github.com/joscha/play-authenticate*/
#Restrict(Application.USER_ROLE)
public static Result profile() {
final User localUser = getLocalUser(session());
return ok(profile.render(localUser));
}
/*Source: https://github.com/joscha/play-authenticate*/
public static Result login() {
return ok(login.render(MyUsernamePasswordAuthProvider.LOGIN_FORM));
}
/*Source: https://github.com/joscha/play-authenticate*/
public static Result doLogin() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
final Form<MyLogin> filledForm = MyUsernamePasswordAuthProvider.LOGIN_FORM
.bindFromRequest();
if (filledForm.hasErrors()) {
// User did not fill everything properly
return badRequest(login.render(filledForm));
} else {
// Everything was filled
return UsernamePasswordAuthProvider.handleLogin(ctx());
}
}
/*Source: https://github.com/joscha/play-authenticate*/
public static Result signup() {
return ok(signup.render(MyUsernamePasswordAuthProvider.SIGNUP_FORM));
}
/*Source: https://github.com/joscha/play-authenticate*/
public static Result jsRoutes() {
return ok(
Routes.javascriptRouter("jsRoutes",
controllers.routes.javascript.Signup.forgotPassword()))
.as("text/javascript");
}
/*Source: https://github.com/joscha/play-authenticate*/
public static Result doSignup() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
final Form<MySignup> filledForm = MyUsernamePasswordAuthProvider.SIGNUP_FORM
.bindFromRequest();
if (filledForm.hasErrors()) {
// User did not fill everything properly
return badRequest(signup.render(filledForm));
} else {
// Everything was filled
// do something with your part of the form before handling the user
// signup
return UsernamePasswordAuthProvider.handleSignup(ctx());
}
}
/*Source: https://github.com/joscha/play-authenticate*/
public static String formatTimestamp(final long t) {
return new SimpleDateFormat("yyyy-dd-MM HH:mm:ss").format(new Date(t));
}
}
Update:
package models;
import play.mvc.Http.Session;
import controllers.*;
import java.util.*;
import play.db.ebean.*;
import play.data.validation.Constraints.*;
import javax.persistence.*;
import play.data.format.*;
import com.avaje.ebean.*;
import java.text.*;
#Entity
public class Journey extends Model {
public SimpleDateFormat simpleTimeFormat = new SimpleDateFormat("hh:mm");
public SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yy");
#Id
public Long id;
#Required
public String start_loc;
#Required
public String end_loc;
#Required
public String participant_type;
#Required
public String date = simpleDateFormat.format(new Date());
#Required
public String time = simpleTimeFormat.format(new Date());
#ManyToOne
public User createUser;
#ManyToOne
public User modifyUser;
public static Finder<Long,Journey> find = new Finder(
Long.class, Journey.class
);
public static List<Journey> all() {
return find.all();
}
public static void create(Journey journey) {
journey.save();
}
public static void delete(Long id) {
find.ref(id).delete();
}
public static List<Journey> searchByAddress(String address) {
return find.where().ilike("start_loc", "%"+address+"%").findList();
}
public void save() {
User logged = Application.getLocalUser(session());
if (logged != null) {
this.createUser = logged;
this.modifyUser = logged;
}
super.save();
}
public void update(Object o) {
User logged = Application.getLocalUser(session());
if (logged != null) {
this.modifyUser = logged;
}
super.update(o);
}
}

You don't need to write it manualy, for an example if you have a Book.java model you can add field for an example updatedBy to identify who was editing record last time, what's more you can override Model's methods save() and update(Object o) to make sure, that these fields will be always updated without additional effort.
#Entity
public class Book extends Model {
#Id
public Integer id;
#ManyToOne
public User createUser;
#ManyToOne
public User modifyUser;
public void save() {
User logged = Application.getLocalUser(session());
if (logged != null) {
this.createUser = logged;
this.modifyUser = logged;
}
super.save();
}
public void update(Object o) {
User logged = Application.getLocalUser(session());
if (logged != null) {
this.modifyUser = logged;
}
super.update(o);
}
// other fields/methods
}

Related

Why can't the database still not save the data with my current TypeConverter?

I am stuck with implementing a TypeConverter to my Database. I have added the TypeConverters but it still keeps saying that it cannot figure out how to save the field into the database. Or maybe I have missed something? I was following this article to create TypeConverters (https://android.jlelse.eu/room-persistence-library-typeconverters-and-database-migration-3a7d68837d6c), which is with my knowledge so far a bit hard to understand.
Any help would be appreciated!
MyGame.java:
package com.riceplant.capstoneproject.room;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import com.riceplant.capstoneproject.data.Cover;
import com.riceplant.capstoneproject.data.Genre;
import com.riceplant.capstoneproject.data.Platform;
import com.riceplant.capstoneproject.data.ReleaseDate;
import com.riceplant.capstoneproject.data.Video;
import java.util.List;
#Entity(tableName = "game")
public class MyGame {
#PrimaryKey(autoGenerate = true)
private Integer mId;
private Cover mCover;
private String mName;
private Double mPopularity;
private String mSummary;
private List<Genre> mGenres;
private List<Platform> mPlatform;
private Double mRating;
private List<ReleaseDate> mReleaseDate;
private List<Video> mVideos;
#Ignore
public MyGame() {
}
public MyGame(Integer id,
Cover cover,
String name,
Double popularity,
String summary,
List<Genre> genres,
List<Platform> platform,
Double rating,
List<ReleaseDate> releaseDate,
List<Video> videos) {
mId = id;
mCover = cover;
mName = name;
mPopularity = popularity;
mSummary = summary;
mGenres = genres;
mPlatform = platform;
mRating = rating;
mReleaseDate = releaseDate;
mVideos = videos;
}
public Integer getId() {
return mId;
}
public void setId(Integer id) {
id = mId;
}
public Cover getCover() {
return mCover;
}
public void setCover(Cover cover) {
cover = mCover;
}
public String getName() {
return mName;
}
public void setName(String name) {
name = mName;
}
public Double getPopularity() {
return mPopularity;
}
public void setPopularity(Double popularity) {
popularity = mPopularity;
}
public String getSummary() {
return mSummary;
}
public void setSummary(String summary) {
summary = mSummary;
}
public List<Genre> getGenres() {
return mGenres;
}
public void setGenres(List<Genre> genres) {
genres = mGenres;
}
public List<Platform> getPlatform() {
return mPlatform;
}
public void setPlatform(List<Platform> platform) {
platform = mPlatform;
}
public Double getRating() {
return mRating;
}
public void setRating(Double rating) {
rating = mRating;
}
public List<ReleaseDate> getReleaseDate() {
return mReleaseDate;
}
public void setReleaseDate(List<ReleaseDate> releaseDate) {
releaseDate = mReleaseDate;
}
public List<Video> getVideos() {
return mVideos;
}
public void setVideos(List<Video> videos) {
videos = mVideos;
}
}
Converters.java
package com.riceplant.capstoneproject.room;
import androidx.room.TypeConverter;
import com.riceplant.capstoneproject.data.Cover;
import com.riceplant.capstoneproject.data.Genre;
import com.riceplant.capstoneproject.data.Platform;
import com.riceplant.capstoneproject.data.Video;
public class Converters {
#TypeConverter
public static Cover toCover(String value) {
return value == null ? null : new Cover();
}
#TypeConverter
public static String toString(Cover value) {
return value == null ? null : value.getUrl();
}
#TypeConverter
public static Genre toGenre(String value) {
return value == null ? null : new Genre();
}
#TypeConverter
public static String toString(Genre value) {
return value == null ? null : value.getName();
}
#TypeConverter
public static Platform toPlatform(String value) {
return value == null ? null : new Platform();
}
#TypeConverter
public static String toString(Platform value) {
return value == null ? null : value.getName();
}
#TypeConverter
public static Video toString(String value) {
return value == null ? null : new Video();
}
#TypeConverter
public static String toVideo(Video value) {
return value == null ? null : value.getVideoId();
}
}
GameRoomDatabase.java
package com.riceplant.capstoneproject.room;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
#Database(entities = {MyGame.class}, version = 3, exportSchema = false)
#TypeConverters({Converters.class})
public abstract class GameRoomDatabase extends RoomDatabase {
private static final String LOG_TAG = GameRoomDatabase.class.getSimpleName();
private static final Object LOCK = new Object();
private static final String DATABASE_NAME = "gameslist";
private static GameRoomDatabase sInstance;
public static GameRoomDatabase getInstance(Context context) {
if (sInstance == null) {
synchronized (LOCK) {
sInstance = Room.databaseBuilder(context.getApplicationContext(),
GameRoomDatabase.class, GameRoomDatabase.DATABASE_NAME)
.fallbackToDestructiveMigration()
.build();
}
}
return sInstance;
}
public abstract GameDao gameDao();
}
GameDao.java
package com.riceplant.capstoneproject.room;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
#Dao
public interface GameDao {
#Query("SELECT * FROM game ORDER BY mId")
LiveData<List<MyGame>> loadAllGames();
#Insert
void insertGame(MyGame myGame);
#Update(onConflict = OnConflictStrategy.REPLACE)
void updateGame(MyGame myGame);
#Delete
void deleteGame(MyGame myGame);
#Query("SELECT * FROM game WHERE mId = :id")
MyGame loadGameById(int id);
}
GameViewModel
package com.riceplant.capstoneproject.room;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class GameViewModel extends AndroidViewModel {
private LiveData<List<MyGame>> games;
public GameViewModel(#NonNull Application application) {
super(application);
GameRoomDatabase database = GameRoomDatabase.getInstance(this.getApplication());
games = database.gameDao().loadAllGames();
}
public LiveData<List<MyGame>> getGames() {
return games;
}
}
Your DB contains Lists of Genre, Platform, ReleaseDate and Video. SQLite supports column types of INTEGER, REAL, TEXT and BLOB. You must provide methods for conversion of your List types to/from String(TEXT) or one of the other supported SQLite types.
For example:
#TypeConverter
public static List<Genre> toGenreList(String value) {
// TODO conversion code
}
#TypeConverter
public static String toString(List<Genre> value) {
// TODO conversion code
}

Java/Spring - Object references an unsaved transient instance

Well, my issue is related to when I try to save an entity (Parade) which has a collection of other entity (AcmeFloat) using the corresponding default CRUD method in convenient repository (the code is attached below). When it reaches the save() method, it throws an exception.
I tried to save the pertinent entities of AcmeFloat class which need to be updated by hand, but, whatever I do (whether save first the Parade updated and later update and save each AcmeFloat or inside out) raises an exception.
So I went into Stack Overflow and the solution I found is putting a 'cascade=CascadeType.ALL' inside the #ManyToMany anotation, without success. I tried also to do both things, which also fails.
Here is the code:
Parade (Domain Class):
package domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.format.annotation.DateTimeFormat;
#Entity
#Access(AccessType.PROPERTY)
public class Parade extends DomainEntity {
// Fields -----------------------------------------------------------------
private String title;
private String description;
private Date moment;
private String ticker;
private boolean isDraft;
// Relationships ----------------------------------------------------------
private Brotherhood brotherhood;
private Collection<AcmeFloat> acmeFloats;
// Field access methods ---------------------------------------------------
#NotBlank
public String getTitle() {
return this.title;
}
public void setTitle(final String title) {
this.title = title;
}
#NotBlank
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "dd/MM/yyyy HH:mm")
public Date getMoment() {
return this.moment;
}
public void setMoment(final Date moment) {
this.moment = moment;
}
#NotBlank
#Pattern(regexp = "^([\\d]){6}-([A-Z]){5}$")
#Column(unique = true)
public String getTicker() {
return this.ticker;
}
public void setTicker(final String ticker) {
this.ticker = ticker;
}
#Basic
public boolean getIsDraft() {
return this.isDraft;
}
public void setIsDraft(final boolean isDraft) {
this.isDraft = isDraft;
}
// Relationship access methods --------------------------------------------
#Valid
#ManyToOne(optional = true)
public Brotherhood getBrotherhood() {
return this.brotherhood;
}
public void setBrotherhood(final Brotherhood brotherhood) {
this.brotherhood = brotherhood;
}
#Valid
#ManyToMany(mappedBy = "parades", cascade = CascadeType.ALL)
public Collection<AcmeFloat> getAcmeFloats() {
return new ArrayList<AcmeFloat>(this.acmeFloats);
}
public void setAcmeFloats(final Collection<AcmeFloat> acmeFloats) {
this.acmeFloats = acmeFloats;
}
}
AcmeFloat (Domain Class):
package domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
#Entity
#Access(AccessType.PROPERTY)
public class AcmeFloat extends DomainEntity {
// Fields -----------------------------------------------------------------
private String title;
private String description;
private List<String> pictures;
// Relationships ----------------------------------------------------------
private Collection<Parade> parades;
private Brotherhood brotherhood;
// Field access methods ---------------------------------------------------
#NotNull
#NotBlank
public String getTitle() {
return this.title;
}
public void setTitle(final String title) {
this.title = title;
}
#NotNull
#NotBlank
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
//Optional
//#URL
#NotNull
#ElementCollection
public List<String> getPictures() {
return this.pictures;
}
public void setPictures(final List<String> pictures) {
this.pictures = pictures;
}
// Relationship access methods --------------------------------------------
#ManyToMany(cascade = CascadeType.ALL)
#Valid
public Collection<Parade> getParades() {
return this.parades;
}
public void setParades(final Collection<Parade> parades) {
this.parades = new ArrayList<Parade>(parades);
}
#ManyToOne
#Valid
public Brotherhood getBrotherhood() {
return this.brotherhood;
}
public void setBrotherhood(final Brotherhood brotherhood) {
this.brotherhood = brotherhood;
}
}
ParadeForm (Form Object):
package forms;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import domain.AcmeFloat;
public class ParadeForm {
// Fields -----------------------------------------------------------------
private int id;
private String title;
private String description;
private Date moment;
// Relationships ----------------------------------------------------------
private Collection<AcmeFloat> acmeFloats;
// Field access methods ---------------------------------------------------
#Range(min = 0)
public int getId() {
return this.id;
}
public void setId(final int id) {
this.id = id;
}
#NotBlank
public String getTitle() {
return this.title;
}
public void setTitle(final String title) {
this.title = title;
}
#NotBlank
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "dd/MM/yyyy HH:mm")
public Date getMoment() {
return this.moment;
}
public void setMoment(final Date moment) {
this.moment = moment;
}
// Relationship access methods --------------------------------------------
#NotNull
public Collection<AcmeFloat> getAcmeFloats() {
return this.acmeFloats;
}
public void setAcmeFloats(final Collection<AcmeFloat> acmeFloats) {
this.acmeFloats = acmeFloats;
}
}
ParadeRepository:
package repositories;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import domain.Parade;
#Repository
public interface ParadeRepository extends JpaRepository<Parade, Integer> {
#Query("select p from Parade p where p.ticker like ?1")
List<Parade> findByTicker(String ticker);
#Query("select p from Parade p where p.moment < ?1 and p.isDraft = false")
List<Parade> findBeforeDate(Date date);
#Query("select p from Parade p where p.isDraft = false")
List<Parade> findAllFinal();
#Query("select p from Parade p where p.isDraft = false and brotherhood.userAccount.id = ?1")
List<Parade> findAllFinalByBrotherhoodAccountId(int id);
#Query("select p from Parade p where brotherhood.userAccount.id = ?1")
List<Parade> findAllByBrotherhoodAccountId(int id);
#Query("select p from Parade p join p.brotherhood.enrolments e where e.member.id= ?1")
List<Parade> findPossibleMemberParades(int id);
}
AcmeFloatRepository:
package repositories;
import java.util.Collection;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import domain.AcmeFloat;
#Repository
public interface AcmeFloatRepository extends JpaRepository<AcmeFloat, Integer> {
#Query("select f from AcmeFloat f where f.brotherhood.userAccount.id = ?1")
Collection<AcmeFloat> findAcmeFloats(int principalId);
}
ParadeService:
package services;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Random;
import javax.validation.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import repositories.ParadeRepository;
import security.LoginService;
import domain.AcmeFloat;
import domain.Parade;
import forms.ParadeForm;
#Service
#Transactional
public class ParadeService {
////////////////////////////////////////////////////////////////////////////////
// Managed repository
#Autowired
private ParadeRepository paradeRepository;
////////////////////////////////////////////////////////////////////////////////
// Supporting services
#Autowired
private BrotherhoodService brotherhoodService;
////////////////////////////////////////////////////////////////////////////////
// Supporting services
#Autowired
private Validator validator;
////////////////////////////////////////////////////////////////////////////////
// Ticker generation fields
private static final String TICKER_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final int TICKER_LENGTH = 5;
private final Random random = new Random();
////////////////////////////////////////////////////////////////////////////////
// Constructors
public ParadeService() {
super();
}
////////////////////////////////////////////////////////////////////////////////
// CRUD methods
public Parade create() {
final Parade parade = new Parade();
parade.setBrotherhood(this.brotherhoodService.findByUserAccountId(LoginService.getPrincipal().getId()));
parade.setAcmeFloats(new ArrayList<AcmeFloat>());
parade.setIsDraft(true);
parade.setDescription("");
parade.setTitle("");
if (parade.getTicker() == null || parade.getTicker().isEmpty()) {
final Calendar calendar = new GregorianCalendar();
String dateString = "";
dateString += String.format("%02d", calendar.get(Calendar.YEAR) % 100);
dateString += String.format("%02d", calendar.get(Calendar.MONTH) + 1);
dateString += String.format("%02d", calendar.get(Calendar.DAY_OF_MONTH));
dateString += "-";
String ticker;
do {
ticker = dateString;
for (int i = 0; i < ParadeService.TICKER_LENGTH; ++i)
ticker += ParadeService.TICKER_ALPHABET.charAt(this.random.nextInt(ParadeService.TICKER_ALPHABET.length()));
} while (this.paradeRepository.findByTicker(ticker).size() > 0);
parade.setTicker(ticker);
}
return parade;
}
public Parade save(final Parade parade) {
Assert.notNull(parade);
//final Parade originalParade = this.paradeRepository.findOne(parade.getId());
//if (originalParade != null)
Assert.isTrue(parade.getIsDraft());
Assert.isTrue(parade.getMoment().after(new Date()));
//TODO: if ticker existe en BBDD, generar nuevo, else, se guarda
return this.paradeRepository.save(parade);
}
public void delete(final Parade parade) {
Assert.notNull(parade);
Assert.isTrue(parade.getIsDraft());
this.paradeRepository.delete(parade);
}
public Parade findOne(final int id) {
return this.paradeRepository.findOne(id);
}
public List<Parade> findAll() {
return this.paradeRepository.findAll();
}
////////////////////////////////////////////////////////////////////////////////
// Ancillary methods
public List<Parade> findWithin30Days() {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DATE, 30);
final Date plus30Days = calendar.getTime();
return this.paradeRepository.findBeforeDate(plus30Days);
}
public List<Parade> findAllByBrotherhoodAccountId(final int id) {
return this.paradeRepository.findAllByBrotherhoodAccountId(id);
}
public List<Parade> findAllFinalByBrotherhoodAccountId(final int id) {
return this.paradeRepository.findAllFinalByBrotherhoodAccountId(id);
}
public List<Parade> findAllFinal() {
return this.paradeRepository.findAllFinal();
}
public List<Parade> findPossibleMemberParades(final int memberId) {
return this.paradeRepository.findPossibleMemberParades(memberId);
}
public Parade reconstruct(final ParadeForm paradeForm, final BindingResult binding) {
Parade result;
if (paradeForm.getId() == 0)
result = this.create();
else
result = this.paradeRepository.findOne(paradeForm.getId());
result.setTitle(paradeForm.getTitle());
result.setDescription(paradeForm.getDescription());
result.setMoment(paradeForm.getMoment());
result.setAcmeFloats(paradeForm.getAcmeFloats());
this.validator.validate(result, binding);
this.paradeRepository.flush();
if (binding.hasErrors())
throw new ValidationException();
return result;
}
}
AcmeFloatService:
package services;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import repositories.AcmeFloatRepository;
import domain.AcmeFloat;
import domain.Parade;
#Service
#Transactional
public class AcmeFloatService {
////////////////////////////////////////////////////////////////////////////////
// Managed repository
#Autowired
private AcmeFloatRepository acmeFloatRepository;
////////////////////////////////////////////////////////////////////////////////
// Supporting services
////////////////////////////////////////////////////////////////////////////////
// Constructors
public AcmeFloatService() {
super();
}
////////////////////////////////////////////////////////////////////////////////
// CRUD methods
public AcmeFloat create() {
final AcmeFloat result = new AcmeFloat();
// set fields
result.setTitle("");
result.setDescription("");
result.setPictures(new ArrayList<String>());
// set relationships
result.setParades(new ArrayList<Parade>());
result.setBrotherhood(null);
return result;
}
public AcmeFloat save(final AcmeFloat acmeFloat) {
Assert.isTrue(acmeFloat != null);
return this.acmeFloatRepository.save(acmeFloat);
}
public Iterable<AcmeFloat> save(final Iterable<AcmeFloat> acmeFloats) {
Assert.isTrue(acmeFloats != null);
return this.acmeFloatRepository.save(acmeFloats);
}
public void delete(final AcmeFloat acmeFloat) {
Assert.isTrue(acmeFloat != null);
this.acmeFloatRepository.delete(acmeFloat);
}
public void delete(final Iterable<AcmeFloat> acmeFloats) {
Assert.isTrue(acmeFloats != null);
this.acmeFloatRepository.delete(acmeFloats);
}
public AcmeFloat findOne(final int id) {
return this.acmeFloatRepository.findOne(id);
}
public List<AcmeFloat> findAll() {
return this.acmeFloatRepository.findAll();
}
////////////////////////////////////////////////////////////////////////////////
// Ancillary methods
public Collection<AcmeFloat> findAcmeFloats(final int id) {
return this.acmeFloatRepository.findAcmeFloats(id);
}
}
ParadeController:
package controllers;
import java.util.Collection;
import javax.validation.Valid;
import javax.validation.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import security.LoginService;
import security.UserAccount;
import services.AcmeFloatService;
import services.BrotherhoodService;
import services.ParadeService;
import domain.AcmeFloat;
import domain.Brotherhood;
import domain.Parade;
import forms.ParadeForm;
#Controller
#RequestMapping("/parade")
public class ParadeController extends AbstractController {
// Services ---------------------------------------------------------------
#Autowired
private ParadeService paradeService;
#Autowired
private BrotherhoodService brotherhoodService;
#Autowired
private AcmeFloatService acmeFloatService;
// Constructors -----------------------------------------------------------
public ParadeController() {
}
// List -------------------------------------------------------------------
#RequestMapping(value = "/brotherhood/list", method = RequestMethod.GET)
public ModelAndView list() {
final ModelAndView result;
Collection<Parade> parades;
parades = this.paradeService.findAllByBrotherhoodAccountId(LoginService.getPrincipal().getId());
result = new ModelAndView("parade/brotherhood/list");
result.addObject("parades", parades);
result.addObject("requestURI", "parade/brotherhood/list.do");
return result;
}
// Create -----------------------------------------------------------------
#RequestMapping(value = "/brotherhood/create", method = RequestMethod.GET)
public ModelAndView create() {
final ModelAndView result;
Parade parade;
parade = this.paradeService.create();
parade.setIsDraft(true);
result = this.createEditModelAndView(parade, "create");
return result;
}
// Edit -------------------------------------------------------------------
#RequestMapping(value = "/brotherhood/edit", method = RequestMethod.GET)
public ModelAndView edit(#RequestParam final int paradeId) {
ModelAndView result;
Parade parade;
parade = this.paradeService.findOne(paradeId);
Assert.notNull(parade);
result = this.createEditModelAndView(parade, "edit");
return result;
}
// Save -------------------------------------------------------------------
#RequestMapping(value = "/brotherhood/edit", method = RequestMethod.POST, params = "save")
public ModelAndView save(#ModelAttribute("parade") final ParadeForm paradeForm, final BindingResult binding) {
ModelAndView result;
Parade parade;
Parade oldParade;
parade = this.paradeService.reconstruct(paradeForm, binding);
oldParade = this.paradeService.findOne(paradeForm.getId());
try {
for(AcmeFloat f : parade.getAcmeFloats()){
Collection<Parade> parades = f.getParades();
parades.add(parade);
f.setParades(parades);
this.acmeFloatService.save(f);
}
if(parade.getId() != 0){
Collection<AcmeFloat> paradesRemoved = oldParade.getAcmeFloats();
paradesRemoved.removeAll(parade.getAcmeFloats());
for(AcmeFloat f : paradesRemoved){
final Collection<Parade> parades = f.getParades();
parades.remove(parade);
f.setParades(parades);
this.acmeFloatService.save(f);
}
}
this.paradeService.save(parade);
result = new ModelAndView("redirect:list.do");
} catch (final ValidationException oops) {
result = this.createEditModelAndView(parade, "edit");
} catch (final Throwable oops) {
result = this.createEditModelAndView(parade, "parade.commit.error", "edit");
}
return result;
}
/*
final Parade paradeUpdated = this.paradeService.reconstruct(paradeForm, binding);
Collection<AcmeFloat> paradesRemoved = new ArrayList<>();
if (paradeForm.getId() != 0)
paradesRemoved = parade.getAcmeFloats();
if (paradeUpdated.getId() != 0)
paradesRemoved.removeAll(paradeUpdated.getAcmeFloats());
final Parade paradeSaved = this.paradeService.save(paradeUpdated);
for (final AcmeFloat f : paradeUpdated.getAcmeFloats()) {
final Collection<Parade> parades = f.getParades();
parades.add(paradeSaved);
f.setParades(parades);
this.acmeFloatService.save(f);
}
if (paradeUpdated.getId() != 0)
for (final AcmeFloat f : paradesRemoved) {
final Collection<Parade> parades = f.getParades();
parades.remove(parade);
f.setParades(parades);
this.acmeFloatService.save(f);
*/
// Delete -----------------------------------------------------------------
#RequestMapping(value = "/brotherhood/edit", method = RequestMethod.POST, params = "delete")
public ModelAndView delete(final Parade parade, final BindingResult binding) {
ModelAndView result;
try {
this.paradeService.delete(parade);
result = new ModelAndView("redirect:list.do");
} catch (final Throwable oops) {
result = this.createEditModelAndView(parade, "parade.commit.error", "edit");
}
return result;
}
// Save in Final Mode -----------------------------------------------------
#RequestMapping(value = "/brotherhood/edit", method = RequestMethod.POST, params = "finalMode")
public ModelAndView finalMode(#Valid final Parade parade, final BindingResult binding) {
ModelAndView result;
if (binding.hasErrors())
result = this.createEditModelAndView(parade, "edit");
else
try {
parade.setIsDraft(false);
this.paradeService.save(parade);
result = new ModelAndView("redirect:list.do");
} catch (final Throwable oops) {
result = this.createEditModelAndView(parade, "parade.commit.error", "edit");
}
return result;
}
// Show -------------------------------------------------------------------
#RequestMapping(value = "/public/show", method = RequestMethod.GET)
public ModelAndView show(#RequestParam final int paradeId) {
ModelAndView result;
Parade parade;
parade = this.paradeService.findOne(paradeId);
Assert.notNull(parade);
Assert.isTrue(parade.getIsDraft());
result = new ModelAndView("parade/public/" + "show");
result.addObject("parade", parade);
// result.addObject("messageCode", null);
return result;
}
// Ancillary Methods ------------------------------------------------------
protected ModelAndView createEditModelAndView(final Parade parade, final String method) {
ModelAndView result;
result = this.createEditModelAndView(parade, null, method);
return result;
}
protected ModelAndView createEditModelAndView(final Parade parade, final String messageCode, final String method) {
final ModelAndView result;
final Brotherhood brotherhood;
final Collection<AcmeFloat> acmeFloats;
final UserAccount userAccount = LoginService.getPrincipal();
brotherhood = this.brotherhoodService.findPrincipal();
acmeFloats = this.acmeFloatService.findAcmeFloats(userAccount.getId());
result = new ModelAndView("parade/brotherhood/" + method);
result.addObject("brotherhood", brotherhood);
result.addObject("acmeFloats", acmeFloats);
result.addObject("parade", parade);
result.addObject("messageCode", messageCode);
return result;
}
}
In the Create case, the flow is the next one: When in the create view after filling form and sending, save() method is called in ParadeController. Its input is a ParadeForm object with id=0. "parade" (the new Parade in this case and the updated Parade in case of edition) and "oldParade" (null in this case but the Parade before the update in update case) objects are created and declared anyway. Then, we go into the try/catch. First, it get the parade's acmeFloats in order to update them adding in their parades collection the just created Parade. But, at first attempt of saving, it throws the following thing:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance
Saving first the new Parade gives the same results. I was intended to, in case it is an edition (so the Parade existed before and can have had AcmeFloats), find the AcmeFloats that have been removed from the Parade and update them and then save the Parade. So I needed the oldParade in edit case to check which AcmeFloats I have to remove the Parade from.
Also, I don't know whether I have to do all this thing with the cascade in #ManyToMany, but just saving the Parade once reconstructed, but it doesn't work anyway, so I decided to post that part of the code so that you figure out how would it work without the cascade.
I've been having troubles with this issue for the last month and before. Thanks in advance.
EDIT 1:
When I put a flush() after saving in the repository, it throws the following exception at saving:
org.springframework.orm.jpa.JpaSystemException: Exception occurred inside getter of domain.Parade.acmeFloats; nested exception is org.hibernate.PropertyAccessException: Exception occurred inside getter of domain.Parade.acmeFloats

java.util.LinkedHashMap cannot be cast to com.common.pojo.myDataDetails

My java class is throwing some error. In my class i am using this to get my data.
((myDataDetails) Names.get(0)).InputParamNames().add("SomeValue");
But it is throwing error
Here is my Pohjo Class.
package common.pojo;
import java.util.Date;
import java.util.List;
public class myDataDetails
{
private String myID;
private List<String> InputParamNames;
private List InputParamData;
public String getmyID() {
return this.myID;
}
public void setmyID(String myID) {
this.myID = myID;
}
public List<String> getInputParamNames() {
return this.InputParamNames;
}
public void setInputParamNames(List<String> InputParamNames) {
this.InputParamNames = InputParamNames;
}
public List getInputParamData() {
return this.InputParamData;
}
public void setInputParamData(List InputParamData) {
this.InputParamData = InputParamData;
}
}
What should I need to change in pojo to avoid this exception.
Your class 'myDataDetails' needs to extend from LinkedHashMap in order to cast it.
What you have right now is a regular POJO class that is not an instance of LinkedHashMap, so you can't cast it as such.
EDIT: It should look like this
package common.pojo;
import java.util.Date;
import java.util.List;
import java.util.LinkedHashMap;
public class myDataDetails extends LinkedHashMap<Object, Object>
{
private String myID;
private List<String> InputParamNames;
private List InputParamData;
public String getmyID() {
return this.myID;
}
public void setmyID(String myID) {
this.myID = myID;
}
public List<String> getInputParamNames() {
return this.InputParamNames;
}
public void setInputParamNames(List<String> InputParamNames) {
this.InputParamNames = InputParamNames;
}
public List getInputParamData() {
return this.InputParamData;
}
public void setInputParamData(List InputParamData) {
this.InputParamData = InputParamData;
}
}

why result not getting in spring data application

I am newbie to spring and java,
I have a case, where i am trying to fetching rows from the mysql table
This is my Controller:
#RequestMapping(value = "/pharmacy/order/dates", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
public PharmacyOrderDateResponse orderDates(#Valid #RequestBody PharmacyOrderDateRequest request) {
List<PrescriptionOrder> pharmacyOrders = prescriptionOrderService.orderDatesByPharmacyId(request.getPharmacyId(), request.getOrderStatus(), true);
if(pharmacyOrders.size() == 0) {
throw new EntityNotFoundException("No pharmacy orders found");
}
PharmacyOrderDateResponse response = new PharmacyOrderDateResponse();
Set<Date> orderDateSet = new HashSet<>();
for(PrescriptionOrder pharmacyOrder : pharmacyOrders) {
//orderDateSet.add(longToDate(pharmacyOrder.getCreatedAt().getTime()));
}
response.setPharmacyId(pharmacyOrders.get(0).getPharmacyId());
response.setStatus(ResponseStatusCode.SUCCESS);
response.setPharmacyOrderDateDetails(orderDateSet);
response.setTotalDates(orderDateSet.size());
return response;
}
The above controller is used to call the service by the function, so that to get the list of prescription orders.
This is my Service:
package com.axonytes.corporate.service;
import java.util.Date;
import java.util.List;
import com.axonytes.corporate.entity.PrescriptionOrder;
public interface PrescriptionOrderService {
List<PrescriptionOrder> orderDatesByPharmacyId(Long labId, String orderStatus, Boolean status);
}
This is my ServiceImpl:
#Service
#Transactional(readOnly = true)
public class PrescriptionOrderServiceImpl implements PrescriptionOrderService {
private PrescriptionOrderRepository prescriptionOrderRepository;
#Autowired
public PrescriptionOrderServiceImpl(PrescriptionOrderRepository prescriptionOrderRepository) {
this.prescriptionOrderRepository = prescriptionOrderRepository;
}
#Override
public List<PrescriptionOrder> orderDatesByPharmacyId(Long pharmacyId, String orderStatus, Boolean status) {
OrderStatusEnum orderStatusEnum = OrderStatusEnum.fromString(orderStatus);
List<PrescriptionOrder> prescriptionOrder = prescriptionOrderRepository
.findByPharmacyIdAndOrderStatus(pharmacyId, orderStatusEnum.getStatus());
return prescriptionOrder;
}
}
The above service is a implementation function to list the orders, where it calls the repository function.
This is my Repository:
package com.axonytes.corporate.repository;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.axonytes.corporate.entity.PrescriptionOrder;
#Repository
public interface PrescriptionOrderRepository extends JpaRepository<PrescriptionOrder, Long>{
//#Query(value = "select * from PrescriptionOrder po WHERE po.pharmacyId = :pharmacyId AND po.orderStatus = :orderStatus AND po.active = :active ORDER BY po.createdAt ASC")
//List<PrescriptionOrder> findByPharmacyIdAndOrderStatus(#Param("pharmacyId") Long pharmacyId, #Param("orderStatus") int orderStatus, #Param("active") Boolean active);
List<PrescriptionOrder> findByPharmacyIdAndOrderStatus(#Param("pharmacyId") Long pharmacyId, #Param("orderStatus") int orderStatus);
}
This is my Entity:
package com.axonytes.corporate.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
#Entity
#DynamicInsert
#DynamicUpdate
#Table(name = "prescription_orders")
public class PrescriptionOrder extends BaseEntity {
private static final long serialVersionUID = -3853355500806579362L;
#Column(name = "prescription_id")
private Long prescriptionId;
#Column(name = "pharmacy_id")
private Long pharmacyId;
#Column(name = "order_status")
private int orderStatus;
public Long getPrescriptionId() {
return prescriptionId;
}
public void setPrescriptionId(Long prescriptionId) {
this.prescriptionId = prescriptionId;
}
public Long getPharmacyId() {
return pharmacyId;
}
public void setPharmacyId(Long pharmacyId) {
this.pharmacyId = pharmacyId;
}
public int getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(int orderStatus) {
this.orderStatus = orderStatus;
}
}
This ismy OrderStatusEnumClass:
package com.axonytes.corporate.util;
public enum OrderStatusEnum {
PENDING(0, "pending"), DESPATCHED(1, "dispatched");
private int status;
private String name;
OrderStatusEnum(int status, String name) {
this.status = status;
this.name = name;
}
public static OrderStatusEnum fromString(String name) {
if(name != null) {
for(OrderStatusEnum orderStatusEnum : OrderStatusEnum.values()) {
if(name.equalsIgnoreCase(orderStatusEnum.toString())) {
return orderStatusEnum;
}
}
}
return null;
}
#Override
public String toString() {
return name;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
I have row values in the mysql:
id prescription_id pharmacy_id order_Status is_active
1 1 6 0 1
I am trying to list a orders by the following api.
http://localhost:8080/pharmacy/order/dates
POST METHOD with JSON VALUE:
{
"pharmacyId":"6",
"orderStatus":"pending"
}
Eventhough i am having 1 rows in the mysql db table, Output i am getting is:
{
"status": "FAILURE",
"errorCode": 0,
"errorMessage": "No pharmacy orders found"
}
Here you are using spring data and name method resolving. So is spring who translate the name of your method with each property in your entity, in that case you don't have to declare any parameter name so change your method to this:
#Repository
public interface PrescriptionOrderRepository extends JpaRepository<PrescriptionOrder, Long>{
List<PrescriptionOrder> findByPharmacyIdAndOrderStatus(Long pharmacyId, int orderStatus);
}
Note: You have an enum OrderStatusEnum but you are saving into the database an integer, I highly recommend you to modify the object to store and change the int for the enum, would be easier to read

i implemented a custom comparator to sort my ArrayList, but listview is still not sorted

OK. i made a listview that can see my custom object names I put in the arraylist. I then wrote code to sort the Object List based on their startdate (sdate).
Cannot find solution to my problem.
However, I do not know how to test if my implementation is working since the listview where I see the objects is NOT being sorted, and retains the order in which I added them to the list. here is the code for reference.
Comparator:
package app.zioueche_travelexpense;
import java.util.Comparator;
public class CustomComparator implements Comparator<Claim> {
#Override
public int compare(Claim c1, Claim c2) {
return c1.getSDate().compareTo(c2.getSDate());
}
}
where getSDate is a method in object Claim that simply returns the attribute sdate assigned to it on creation by the user.
now for the sorting problem:
here is where I sort. look for the comment
package app.zioueche_travelexpense;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import android.text.InputFilter.LengthFilter;
import android.widget.Toast;
public class ClaimsList implements Serializable{
/**
* Claim List Serialization ID
*/
private static final long serialVersionUID = 372301924739907840L;
protected static ArrayList<Claim> claimList;
protected ArrayList<Listener> listeners;
public ClaimsList(){
claimList = new ArrayList<Claim>();
listeners = new ArrayList<Listener>();
}
public Collection<Claim> getClaim(){
return claimList;
}
public void addClaim(Claim string){
claimList.add(string);
if (claimList.size() < 1){//SORTING HAPPENS HERE
Collections.sort(claimList, new CustomComparator());
notifyListeners();
}else{
notifyListeners();
}}
public void deleteClaim(Claim removeclaim){
claimList.remove(removeclaim);
notifyListeners();
}
public static boolean isEmpty(){
return claimList.size()== 0;
}
public void notifyListeners(){
for (Listener listener: listeners){
listener.update();
}
}
public void addListener(Listener l){
listeners.add(l);
}
public void removeListener(Listener l){
listeners.remove(l);
}
}
if you need any more information let me know, but I really need to solve this problem
Here is the CLaim object code:
package app.zioueche_travelexpense;
import java.io.Serializable;
import java.util.Date;
import java.util.ArrayList;
public class Claim implements Serializable{
/**
* Student serialized ID
*/
private static final long serialVersionUID = 3325687864575767244L;
private String Name;
private ArrayList<Expense> expenseList;
static Date sdate;
private Date edate;
private String status;
//Claim object constructor NEED TO ADD STATUS
public Claim(String Name, Date sdate2, Date edate2){
this.Name = Name;
this.expenseList = new ArrayList<Expense>();
this.sdate = sdate2;
this.edate = edate2;
//this.status = status;
}
//get the claim name
public String getName(){
return this.Name;
}
//add an expense to the claim's expense list
public void addExpense(Expense expense){
expenseList.add(expense);
}
//change the name to a string.
public String toString(){
return getName();
}
//return the status of the string
public String getStatus(){
return status;
}
//get the start date of the claim
public Date getSDate(){
return sdate;
}
//get the end date of the claim
public Date getEDate(){
return edate;
}
//change the status of the Claim.
public void editStatus(String status){
this.status = status;
}
public boolean equal(Object compareClaim){
if (compareClaim != null && compareClaim.getClass()==this.getClass()){
return this.equals((Claim) compareClaim);
}else{
return false;
}
}
public int hashCode(){
return ("Claim"+getName()).hashCode();
}
//return the expenses list of the Claim
public ArrayList<Expense> getExpenses() {
// TODO Auto-generated method stub
return expenseList;
}
}
and then the Controller and ClaimsList:
package app.zioueche_travelexpense;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
public class ClaimListController {
private static ClaimsList claimList = null;
static public ClaimsList getClaimList(){
if (claimList == null){
claimList = new ClaimsList();
}
return claimList;
}
public void addClaim(Claim claim){
getClaimList().addClaim(claim);
}
}
package app.zioueche_travelexpense;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import android.text.InputFilter.LengthFilter;
import android.widget.Toast;
public class ClaimsList implements Serial
izable{
/**
* Claim List Serialization ID
*/
private static final long serialVersionUID = 372301924739907840L;
protected static ArrayList<Claim> claimList;
protected ArrayList<Listener> listeners;
public ClaimsList(){
claimList = new ArrayList<Claim>();
listeners = new ArrayList<Listener>();
}
public Collection<Claim> getClaim(){
return claimList;
}
public void addClaim(Claim string){
claimList.add(string);
if (claimList.size() > 1){
Collections.sort(claimList, new CustomComparator());
notifyListeners();
}else{
notifyListeners();
}}
public void deleteClaim(Claim removeclaim){
claimList.remove(removeclaim);
notifyListeners();
}
public static boolean isEmpty(){
return claimList.size()== 0;
}
public void notifyListeners(){
for (Listener listener: listeners){
listener.update();
}
}
public void addListener(Listener l){
listeners.add(l);
}
public void removeListener(Listener l){
listeners.remove(l);
}
}
here is the claim List adapter:
ListView listView = (ListView) findViewById(R.id.claimListView);
Collection<Claim> claims = ClaimListController.getClaimList().getClaim();
final ArrayList<Claim> list = new ArrayList<Claim>(claims);
final ArrayAdapter<Claim> claimAdapter = new ArrayAdapter<Claim>(this, android.R.layout.simple_list_item_1, list);
listView.setAdapter(claimAdapter);
You sort your list only when it has 0 size
Change this condition
if (claimList.size() < 1)
to
if (claimList.size() > 1)
Additionally you have to call the notifyDataSetChanged() method on your adapter to refresh list.

Categories