Flash Scope does not delete variables - jsf-2

I'm having a problem with Flash Scope when I try to set a flash scope variable and then do a redirect. In the console, I get the following trace...
com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing
cookie for the flash. Any values stored to the flash will not be available on the next request.
The idea is pass an id from the first page (search page) to the second page, but if I cancel using immediate, I get the mentioned log, and the flash counter is not incremented anymore.
The code:
(Search bean)
#ManagedBean
#ViewScoped
public class ConsultarPaisBean implements Serializable {
private static final long serialVersionUID = 7947494818704255376L;
#ManagedProperty("#{flash}")
private Flash flash;
#ManagedProperty("#{paisService}")
private PaisService paisService;
private List<Pais> paises;
private PaisFilter paisFilter;
private Pais paisSelected;
#PostConstruct
public void init() {
this.paisFilter = new PaisFilter();
this.paisSelected = null;
this.paises = null;
}
public String irRegistrarPais() {
return MappingUrlConstants.PAIS;
}
public String irModificarPais() {
String respuesta = null;
if (this.paisSelected != null && this.paisSelected.getId() != null) {
flash.put("paisId", this.paisSelected.getId());
respuesta = MappingUrlConstants.PAIS;
}
return respuesta;
}
public String buscarPaises() {
this.paisSelected = null;
this.paises = this.paisService.getPaisByParams(this.paisFilter);
return null;
}
public String limpiarFiltros() {
this.paisFilter = new PaisFilter();
return null;
}
public List<Pais> getPaises() {
return paises;
}
public void setPaises(List<Pais> paises) {
this.paises = paises;
}
public PaisFilter getPaisFilter() {
return paisFilter;
}
public void setPaisFilter(PaisFilter paisFilter) {
this.paisFilter = paisFilter;
}
public Pais getPaisSelected() {
return paisSelected;
}
public void setPaisSelected(Pais paisSelected) {
this.paisSelected = paisSelected;
}
public void setPaisService(PaisService paisService) {
this.paisService = paisService;
}
public void setFlash(Flash flash) {
this.flash = flash;
}
}
(Add/Update bean)
#ManagedBean
#ViewScoped
public class PaisBean implements Serializable {
private static final long serialVersionUID = 3604521826400240955L;
#ManagedProperty("#{paisService}")
private PaisService paisService;
#ManagedProperty("#{flash}")
private Flash flash;
private Pais pais;
#PostConstruct
public void init() {
if (this.flash.get("paisId") != null) {
Long id = (Long) this.flash.get("paisId");
this.pais = this.paisService.getPaisById(id);
} else {
this.pais = new Pais();
}
}
public String registrarPais() {
String mensajeExito = null;
if (this.pais.getId() == null) {
this.paisService.save(this.pais);
mensajeExito = MessageUtils.getMessage("org.siae.commons.messages.general", "pais.registrar.exito",
new Object[] { this.pais.getNombre() });
} else {
this.paisService.update(this.pais);
mensajeExito = MessageUtils.getMessage("org.siae.commons.messages.general", "pais.modificar.exito",
new Object[] { this.pais.getNombre() });
}
FacesUtils.addInfoMessage(mensajeExito);
return MappingUrlConstants.CONSULTAR_PAIS;
}
public String irConsultarPais() {
return MappingUrlConstants.CONSULTAR_PAIS;
}
public void setPaisService(PaisService paisService) {
this.paisService = paisService;
}
public void setFlash(Flash flash) {
this.flash = flash;
}
public Pais getPais() {
return pais;
}
public void setPais(Pais pais) {
this.pais = pais;
}
}
I appreciate your help.

Related

Updating adapter of AutoCompleteTextView from LiveData

I have a AutoCompleteTextView that I give it 2 different adapters depending on the amount of text that is being present at the textview - if it has 0 characters I want it to display a list of "recently searched" strings adapter, while if it has more than 1 characters I want it to display auto completion list.
My getRecentlySearchedQueries method along with the RecentSearchedViewModel-
private List<String> recentlySearchedQueries = new ArrayList<>(); // pasted from the top of the class
#Override
public void getRecentlySearchedQueries() {
recentSearchViewModel.getAllQueries().observe(getActivity(), databaseRecentlySearchList -> {
if (databaseRecentlySearchList == null) {
return;
}
for (int i = 0; i < databaseRecentlySearchList.size(); i++) {
Log.d("localDBValue", "Added value - " + databaseRecentlySearchList.get(i).toString() + "\n");
String query = databaseRecentlySearchList.get(i).getQuery();
recentlySearchedQueries.add(query);
}
//Log.d("localDBValue", "recent search list value - " + recentlySearchedQueries);
});
}
public class RecentSearchViewModel extends AndroidViewModel {
private RecentSearchRepository recentSearchRepository;
private LiveData<List<RecentSearchModel>> allRecentlySearched;
public RecentSearchViewModel(#NonNull Application application) {
super(application);
recentSearchRepository = new RecentSearchRepository(application);
allRecentlySearched = recentSearchRepository.getAllRecentSearches();
}
public void insert(RecentSearchModel model) {
recentSearchRepository.insert(model);
}
public void update(RecentSearchModel model) {
// add implementation in the future if needed
}
public void delete(RecentSearchModel model) {
// add implementation in the future if needed
}
public LiveData<List<RecentSearchModel>> getAllQueries() {
return allRecentlySearched;
}
}
public class RecentSearchRepository {
private RecentSearchDao recentSearchDao;
private LiveData<List<RecentSearchModel>> allRecentSearches;
public RecentSearchRepository(Application application) {
MarketplaceDatabase database = MarketplaceDatabase.getRecentSearchInstance(application);
recentSearchDao = database.recentSearchDao();
allRecentSearches = recentSearchDao.getRecentSearchList();
}
public void insert(RecentSearchModel model) {
new RecentSearchRepository.InsertRecentSearchAsyncTask(recentSearchDao).execute(model);
}
public void update (RecentSearchModel model) {
//TODO - implement in future if needed
}
public void delete(RecentSearchModel model) {
//TODO - implement in future if needed
}
public LiveData<List<RecentSearchModel>> getAllRecentSearches() {
return allRecentSearches;
}
private static class InsertRecentSearchAsyncTask extends AsyncTask<RecentSearchModel, Void, Void> {
private RecentSearchDao recentSearchDao;
public InsertRecentSearchAsyncTask(RecentSearchDao recentSearchDao) {
this.recentSearchDao = recentSearchDao;
}
#Override
protected Void doInBackground(RecentSearchModel... recentSearchModels) {
recentSearchDao.insert(recentSearchModels[0]);
return null;
}
}
private static class UpdateRecentSearchAsyncTask extends AsyncTask<RecentSearchModel, Void, Void> {
private RecentSearchDao recentSearchDao;
public UpdateRecentSearchAsyncTask(RecentSearchDao recentSearchDao) {
this.recentSearchDao = recentSearchDao;
}
#Override
protected Void doInBackground(RecentSearchModel... recentSearchModels) {
recentSearchDao.update(recentSearchModels[0]);
return null;
}
}
}
#Dao
public interface RecentSearchDao {
#Insert()
void insert(RecentSearchModel model);
#Update
void update(RecentSearchModel model);
#Delete
void delete(RecentSearchModel model);
#Query("select * from recent_search_table")
LiveData<List<RecentSearchModel>> getRecentSearchList();
}
#Entity(tableName = "recent_search_table")
public class RecentSearchModel {
#PrimaryKey(autoGenerate = true)
private int ID;
private String query;
public RecentSearchModel(){
}
public RecentSearchModel(String query) {
this.query = query;
}
public void setID(int ID) {
this.ID = ID;
}
public int getID() {
return ID;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
#Override
public String toString() {
return "RecentSearchModel{" +
"query='" + query + '\'' +
'}';
}
#Override
public boolean equals(#Nullable Object obj) {
if (obj instanceof RecentSearchModel)
return this.query.equalsIgnoreCase(((RecentSearchModel) obj).query);
return false;
}
}
So, what I am doing here is for start getting all values inside my local DB and adding them to my String list that is part of the adapter. So far so good.
The issue I am facing is that the adapter won't show the amount of strings available in the list that populates it. In fact, it sometimes shows a view half-cut with wierd information, sometimes does not show anything and sometimes shows part of the corrent information. What am I missing?
Another thing I am facing is that the "recently searched" adapter won't work when clicking on the AutoCompleteTextView - it only works when typing and deleting values so the char length is 0. How can I make it work from start of focus?
Here is the way I am populating the information to the ViewModel -
/**
* Shows the searched products following
*/
#Override
public void getSearchedProducts(String searchedQuery) {
MarketplaceUtils.getSearchedProducts(searchedQuery, marketApiCalls, false, initialSearchTake, initialMarketplacePage, new MarketplaceUtils.OnProductsFetchCompleteListener() {
#Override
public void onSuccess(List<MiniProductModel> list) {
if (!searchedQuery.equals(currentSearchedText))
return;
if (list == null) {
//reaching here means we do not have a result to show to the UI so we empty the list.
currentProductList.clear();
productsAdapter.notifyDataSetChanged();
return;
}
if (searchedQuery.length() > 3 && searchAutoCompleteStrings.contains(searchedQuery)) {
Log.d("localDBValue", "searchedValue - " + searchedQuery);
recentSearchViewModel.insert(new RecentSearchModel(searchedQuery));
}
mPresenter.setDiscoverProductsLayoutVisibility(View.GONE);
currentProductList.clear();
currentProductList.addAll(list);
productsAdapter.notifyDataSetChanged();
}
#Override
public void onError(Throwable throwable) {
Log.d("searchedProducts", throwable.getMessage());
}
});
}
The default behaviour for #Insert method of Room is OnConflictStrategy.ABORT - so what I did is to implement equals() method to verify that the RecentSearchModels that are being compared are compared by their string value. Still does seems to effect anything.

ASP.NET MVC 5 SignalR, SqlDependency and EntityFramework 6 - the sqlparameter is already contained by another sqlparametercollection

I am beginner with SignalR and SQLDepedency. I am trying to implement SignalR using EF Code First Approach. I am getting the error The sqlparameter is already contained by another sqlparametercollection if I am using where condition in LINQ class.
public class MessageHub : Hub
{
internal NotifierEntity NotifierEntity { get; private set; }
private MyDbContext db = new MyDbContext();
public void DispatchToClient()
{
Clients.All.broadcastMessage("Refresh");
}
public void Initialize(String userName)
{
if (!string.IsNullOrEmpty(userName))
{
NotifierEntity = db.GetNotifierEntity<Messages>(db.Messages.Where(x=>x.ApplicationUser.UserName== userName && !x.Status));
if (NotifierEntity == null)
return;
Action<String> dispatcher = (t) => { DispatchToClient(); };
PushSqlDependency.Instance(NotifierEntity, dispatcher);
}
}
}
The NotifierEntity Class
public class NotifierEntity
{
ICollection<SqlParameter> sqlParameters = new List<SqlParameter>();
public String SqlQuery { get; set; }
public String SqlConnectionString { get; set; }
public ICollection<SqlParameter> SqlParameters
{
get
{
return sqlParameters;
}
set
{
sqlParameters = value;
}
}
public static NotifierEntity FromJson(String value)
{
if (String.IsNullOrEmpty(value))
throw new ArgumentNullException("NotifierEntity Value can not be null!");
return new JavaScriptSerializer().Deserialize<NotifierEntity>(value);
}
}
public static class NotifierEntityExtentions
{
public static String ToJson(this NotifierEntity entity)
{
if (entity == null)
throw new ArgumentNullException("NotifierEntity can not be null!");
return new JavaScriptSerializer().Serialize(entity);
}
}
public class PushSqlDependency
{
static PushSqlDependency instance = null;
readonly SqlDependencyRegister sqlDependencyNotifier;
readonly Action<String> dispatcher;
public static PushSqlDependency Instance(NotifierEntity notifierEntity, Action<String> dispatcher)
{
if (instance == null)
instance = new PushSqlDependency(notifierEntity, dispatcher);
return instance;
}
private PushSqlDependency(NotifierEntity notifierEntity, Action<String> dispatcher)
{
this.dispatcher = dispatcher;
sqlDependencyNotifier = new SqlDependencyRegister(notifierEntity);
sqlDependencyNotifier.SqlNotification += OnSqlNotification;
}
internal void OnSqlNotification(object sender, SqlNotificationEventArgs e)
{
dispatcher("Refresh123");
}
}
public class SqlDependencyRegister
{
public event SqlNotificationEventHandler SqlNotification;
readonly NotifierEntity notificationEntity;
internal SqlDependencyRegister(NotifierEntity notificationEntity)
{
this.notificationEntity = notificationEntity;
RegisterForNotifications();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security",
"CA2100:Review SQL queries for security vulnerabilities")]
void RegisterForNotifications()
{
using (var sqlConnection = new SqlConnection(notificationEntity.SqlConnectionString))
using (var sqlCommand = new SqlCommand(notificationEntity.SqlQuery, sqlConnection))
{
foreach (var sqlParameter in notificationEntity.SqlParameters)
{
sqlCommand.Parameters.Add(sqlParameter);
}
sqlCommand.Notification = null;
var sqlDependency = new SqlDependency(sqlCommand);
sqlDependency.OnChange += OnSqlDependencyChange;
if (sqlConnection.State == ConnectionState.Closed)
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
}
}
void OnSqlDependencyChange(object sender, SqlNotificationEventArgs e)
{
if (SqlNotification != null)
SqlNotification(sender, e);
RegisterForNotifications();
}
}
public delegate void SqlNotificationEventHandler(object sender, SqlNotificationEventArgs e);
If I am using the same query without any parameters, the code is working perfectly. I can see the database changes instantly in frontend. The issue is coming after added a parameter in Where clause.
I got this idea from below link
https://www.codeproject.com/Tips/1075852/ASP-NET-MVC-SignalR-SqlDependency-and-EntityFramew
Sourcecode link
we.tl/njwwLl8g36

Using the "version" annotation in a document with spring boot elasticearch

i'm using spring-boot-starter-data-elasticsearch (1.4.0.M3).
I'm unable to get the version (_version in elasticsearch query result) of a document using the annoation "version".
Any idea why the annotation isn't working ?
f.e.:
#GwtCompatible
#Document(indexName = "myIndexName")
public class Catalog implements Serializable {
private List<GroupProduct> groups;
#Id
private String uuid;
#Version
private Long version;
#Field(type = FieldType.Nested)
private List<Product> products;
private String label;
#NotEmpty
private String organizationUuid;
private List<String> organizationUnitUuids;
private Date updateDate;
private List<VAT> vats;
public Catalog() {
}
public List<GroupProduct> getGroups() {
return groups;
}
public List<Product> getProducts() {
return products;
}
public Date getUpdateDate() {
return updateDate;
}
public void setGroups(List<GroupProduct> groups) {
this.groups = groups;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public List<VAT> getVats() {
return vats;
}
public void setVats(List<VAT> vats) {
this.vats = vats;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getOrganizationUuid() {
return organizationUuid;
}
public void setOrganizationUuid(String organizationUuid) {
this.organizationUuid = organizationUuid;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public List<String> getOrganizationUnitUuids() {
return organizationUnitUuids;
}
public void setOrganizationUnitUuids(List<String> organizationUnitUuids) {
this.organizationUnitUuids = organizationUnitUuids;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}
Spring Data Elasticsearch (as of version 2.0.2) seems to have only partial support for the #Version annotation. If you annotate a document with a version field, it will be used when indexing a document. It will tell Elasticsearch that the document being saved is that specified version. If the new version is less than or equal to the version of the current document, Elasticsearch will throw a VersionConflictEngineException.
Unfortunately, Spring does not appear to populate this version field when a document is retrieved. As far as I can tell, this makes the version annotation useless. Perhaps the project will add this support in the near future. In the meantime, I have found a workaround by extending the default ResultMapper that Spring uses:
public class ExtendedResultMapper extends DefaultResultMapper {
protected MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
public ExtendedResultMapper(MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
super(mappingContext);
this.mappingContext = mappingContext;
}
#Override
public <T> T mapResult(GetResponse response, Class<T> clazz) {
T result = super.mapResult(response, clazz);
if (result != null) {
setPersistentEntityVersion(result, response.getVersion(), clazz);
}
return result;
}
#Override
public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
LinkedList<T> results = super.mapResults(responses, clazz);
if (results != null) {
for (int i = 0; i < results.size(); i++) {
setPersistentEntityVersion(results.get(i), responses.getResponses()[i].getResponse().getVersion(), clazz);
}
}
return results;
}
private <T> void setPersistentEntityVersion(T result, Long version, Class<T> clazz) {
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
PersistentProperty<ElasticsearchPersistentProperty> versionProperty = mappingContext.getPersistentEntity(clazz).getVersionProperty();
if (versionProperty != null && versionProperty.getType().isAssignableFrom(Long.class)) {
Method setter = versionProperty.getSetter();
if (setter != null) {
try {
setter.invoke(result, version);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
}
}
You can tell Spring to use this version instead of the default mapper as follows:
#Autowired
private Client client;
#Bean
public ElasticsearchTemplate elasticsearchTemplate() {
MappingElasticsearchConverter converter = new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext());
ExtendedResultMapper mapper = new ExtendedResultMapper(converter.getMappingContext());
return new ElasticsearchTemplate(client, converter, mapper);
}
Note that the version is only populated for Get or Multi-Get requests. Search results do not include version information.
You could also use this same approach to extract other information from the GetResponse objects.
Using this code, if you get a document and then try to save it back, it will fail unless you increment the version.

Simple relationships not mapped with queryForObject

I have one question. I am using neo4j-ogm snapshot 1.5 .
I have the following classes:
#NodeEntity
public abstract class Entity {
#GraphId
protected Long id;
#Expose
protected String code = null;
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || id == null || getClass() != o.getClass())
return false;
Entity entity = (Entity) o;
if (!id.equals(entity.id))
return false;
return true;
}
#Override
public int hashCode() {
return (id == null) ? -1 : id.hashCode();
}
public Long getId(){
return id;
}
public void setId(Long neo4jId){
this.id = neo4jId;
}
public String getCode(){
return code;
}
public void setCode(String code){
this.code = code;
}
}
public class PropertyGroup extends Entity{
#Expose
private String name;
public PropertyGroup(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class User extends Entity {
private Long registration_date;
private Long last_login_date;
private Boolean is_admin = false;
private String push_dev;
private String push_id;
private Boolean push_enabled = false;
#Expose
private String avatar;
#Expose
private String avatarUrl;
#Expose
private String name;
#Expose
private volatile String password;
#Expose
private int likes = 0;
#Expose
private int questionCount = 0;
#Expose
private int followersCount = 0;
#Expose
private boolean isFollowing = false;
// public Set<UserPropertyRelation> properties;
// #Relationship(type = ModelRelType.ANSWERED)
// public Set<UserAnsweredRelation> userAnswers;
//
// #Relationship(type = ModelRelType.LIKES)
// private Set<LikesQuestionRelation> questionsLiked;
#Expose
#Relationship(type = ModelRelType.HAS_PROPERTY)
private Set<PropertyGroup> properties;
// private Profile userProfile;
// private List<Fact> facts;
// #Expose
// #Relationship(type = ModelRelType.OWNS)
// private List<Question> questions;
public User(){
// this.properties = new LinkedHashSet<UserPropertyRelation>();
// this.userAnswers = new LinkedHashSet<UserAnsweredRelation>();
// this.userProperties = new HashSet<PropertyGroup>();
// this.setFacts(new ArrayList<Fact>());
this.properties = new HashSet<PropertyGroup>();
}
public User(long regDate, long lastLoginDate, boolean isAdmin,
String pushDev, String pushId, boolean pushEnabled){
this();
this.registration_date = regDate;
this.last_login_date = lastLoginDate;
this.is_admin = isAdmin;
this.push_dev = pushDev;
this.push_id = pushId;
this.push_enabled = pushEnabled;
}
// public void addUserAnsweredRelation(UserAnsweredRelation answer){
// answer.setStartNode(this);
// this.userAnswers.add(answer);
// }
//
// public Set<UserAnsweredRelation> getUserAnsweredRelations() {
// return this.userAnswers;
// }
// public void setUserAnsweredRelations(Set<UserAnsweredRelation> userAnswers){
// for(UserAnsweredRelation a : userAnswers){
// a.setStartNode(this);
// }
//
// this.userAnswers = userAnswers;
// }
//
// public void addUserPropertyRelation(UserPropertyRelation rel){
// rel.setUser(this);
// properties.add(rel);
// }
//
// public void setUserPropertyRelations(Set<UserPropertyRelation> properties){
// for(UserPropertyRelation r: properties){
// r.setUser(this);
// }
//
// this.properties = properties;
// }
// public Set<UserPropertyRelation> getUserPropertyRelations(){
// return this.properties;
// }
public long getRegistrationDate() {
return registration_date;
}
public void setRegistrationDate(long registrationDate) {
this.registration_date = registrationDate;
}
public long getLastLoginDate() {
return last_login_date;
}
public void setLastLoginDate(long lastLoginDate) {
this.last_login_date = lastLoginDate;
}
public boolean isAdmin() {
return is_admin;
}
public void setAdmin(boolean isAdmin) {
this.is_admin = isAdmin;
}
public String getPushDev() {
return push_dev;
}
public void setPushDev(String pushDev) {
this.push_dev = pushDev;
}
public String getPushId() {
return push_id;
}
public void setPushId(String pushId) {
this.push_id = pushId;
}
public boolean isPushEnabled() {
return push_enabled;
}
public void setPushEnabled(boolean pushEnabled) {
this.push_enabled = pushEnabled;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<PropertyGroup> getProperties() {
return properties;
}
public void setProperties(Set<PropertyGroup> properties) {
this.properties = properties;
}
// public Profile getUserProfile() {
// return userProfile;
// }
//
// public void setUserProfile(Profile userProfile) {
// this.userProfile = userProfile;
// }
// public Set<LikesQuestionRelation> getQuestionsLiked() {
// return questionsLiked;
// }
//
// public void setQuestionsLiked(Set<LikesQuestionRelation> likes) {
// this.questionsLiked = likes;
// }
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
// public List<Fact> getFacts() {
// return facts;
// }
//
// public void setFacts(List<Fact> facts) {
// this.facts = facts;
// }
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
public int getLikes() {
return likes;
}
public void setLikes(int likes) {
this.likes = likes;
}
public int getQuestionCount() {
return questionCount;
}
public void setQuestionCount(int questionCount) {
this.questionCount = questionCount;
}
public int getFollowersCount() {
return followersCount;
}
public void setFollowersCount(int followersCount) {
this.followersCount = followersCount;
}
public boolean isFollowing() {
return isFollowing;
}
public void setFollowing(boolean isFollowing) {
this.isFollowing = isFollowing;
}
// public List<Question> getQuestions() {
// return questions;
// }
//
// public void setQuestions(List<Question> questions) {
// this.questions = questions;
// }
When I am trying to do the following:
SessionFactory sessionFactory = new SessionFactory(modelsPackageName);
Session session = sessionFactory.openSession(url);
String cypher = "MATCH (u:User {code: {CODE}})-[h:HAS_PROPERTY]->(pg:PropertyGroup) " +
"RETURN u, h, pg";
Map<String, Object> params = new HashMap<String, Object>();
params.put("CODE", "fc48b19ba6f8427a03d6e5990bcef99a28f55592b80fe38731cf805ed188cabf");
// System.out.println(Util.mergeParamsWithCypher(cypher, params));
User u = session.queryForObject(User.class, cypher, params);
The user Object (u) never contains any properties (PropertyGroup entity is not mapped).
What am I doing wrong?
Any help would be appreciated.
Regards,
Alex
If you're using queryForObject return just one column- the object, in your case u.
Neo4j OGM 1.x does not support mapping of custom query results to domain entities, so you will have to return the entity ID, and then do an additional load-by-id specifying a custom depth.
OGM 2.0 (currently 2.0.0-M01) does support mapping custom query results to entities. Your query will remain the same (i.e. return u,h,pg) but instead you'll use the query() method that returns a Result. From the result, you'll be able to get your User entity by column-name u and it'll be hydrated with the PropertyGroups it is related to.
Update:
The dependencies for OGM 2.0.0-M01 are
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-api</artifactId>
<version>2.0.0-M01</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>2.0.0-M01</version>
</dependency>
Be sure to read the about the configuration changes since you're upgrading from OGM 1.x http://neo4j.com/docs/ogm/java/2.0.0-M01/#reference_setup
A summary of new features: http://neo4j.com/blog/neo4j-ogm-2-0-milestone-1/

p:selectOneMenu not calling setter on form submit

I'm kinda new to JSF and primefaces and I'm running into a very annoying problem.
I'm making a very basic application to learn a bit more about primefaces. I have a simple form that has several textual input fields, two datepickers and one dropdown (selectOneMenu).
Everything works all values are put in the backing bean when I submit the form, except for the value from the dropdown menu. The setter for that item is never called. And the application does not call the public void saveNewActivity(ActionEvent evt) method on the controller as defined on the commandbutton. When I however remove or comment out the dropdown menu in html it does call that method (but the field for the dropdown menu is obviously null).
I've been trying things for nearly two days, and still can't get this to work properly.
I have the following code (snippets):
My html/jsf code
<div id="newActivitycontent">
<h:form id="newActivityForm">
<h:messages id="messages"/>
<table>
<tr>
<td>Gebruiker:</td>
<td><p:selectOneMenu value="#{plannedActivityController.newActivity.organiser}}"
converter="#{userConverter}">
<f:selectItem itemLabel="Kies een gebruiker" itemValue=""/>
<f:selectItems value="#{plannedActivityController.users}" var="user"
itemLabel="#{user.firstname} #{user.lastname}" itemValue="#{user}"/>
</p:selectOneMenu></td>
</tr>
<tr>
<td>Titel:</td>
<td><p:inputText value="#{plannedActivityController.newActivity.name}"/></td>
</tr>
<tr>
<td>Beschrijving:</td>
<td><p:inputText value="#{plannedActivityController.newActivity.desctription}"/></td>
</tr>
<tr>
<td>Startdatum:</td>
<td><p:calendar value="#{plannedActivityController.newActivity.startDateDate}"/></td>
</tr>
<tr>
<td>Einddatum:</td>
<td><p:calendar value="#{plannedActivityController.newActivity.endDateDate}"/></td>
</tr>
</table>
<p:commandButton id="btnSaveNewActivity" value="Opslaan"
actionListener="#{plannedActivityController.saveNewActivity}"
update=":overviewForm:activityTable messages"/>
<p:commandButton id="btnCancelNewActivity" value="Annuleren"
actionListener="#{plannedActivityController.cancelNewActivity}" onclick="hideAddNewUI()"
update=":overviewForm:activityTable" type="reset" immediate="true"/>
</h:form>
</div>
The controller that is used by that code:
#Named
#SessionScoped
public class PlannedActivityController implements Serializable {
#Inject
private ApplicationModel appModel;
#Inject
private SessionModel sessionModel;
#Inject
private ActivityMapper activityMapper;
#Inject
private UserMapper userMapper;
private ActivityBean newActivity;
private ActivityBean selectedActivity;
private List<ActivityBean> activities;
private List<UserBean> users;
public PlannedActivityController() {
}
#PostConstruct
public void onCreated() {
convertActivities();
onNewActivity();
users = userMapper.mapToValueObjects(appModel.getUsers());
}
public void convertActivities() {
List<PlannedActivity> originalActivities = appModel.getActivities();
this.activities = activityMapper.mapToValueObjects(originalActivities);
}
public void onRowEditComplete(RowEditEvent event) {
System.out.println("row edited : " + event.getObject());
//TODO: save changes back to db!
}
public void onRowSelectionMade(SelectEvent event) {
System.out.println("row selected : " + event.getObject());
selectedActivity = (ActivityBean)event.getObject();
}
//Activity crud methods
public void onNewActivity() {
newActivity = new ActivityBean();
newActivity.setId(new Date().getTime());
}
public void saveNewActivity(ActionEvent evt) {
PlannedActivity newAct = activityMapper.mapToEntity(newActivity);
if(newAct != null) {
appModel.getActivities().add(newAct);
}
convertActivities();
}
public void cancelNewActivity() {
//TODO: cleanup.
}
public void deleteSelectedActivity() {
if(selectedActivity != null) {
activities.remove(selectedActivity);
appModel.setActivities(activityMapper.mapToEntities(activities));
convertActivities();
} else {
//TODO: show error or information dialog, that delete cannot be done when nothing has been selected!
}
}
//Getters & Setters
public ApplicationModel getAppModel() {
return appModel;
}
public void setAppModel(ApplicationModel appModel) {
this.appModel = appModel;
}
public SessionModel getSessionModel() {
return sessionModel;
}
public void setSessionModel(SessionModel sessionModel) {
this.sessionModel = sessionModel;
}
public ActivityMapper getActivityMapper() {
return activityMapper;
}
public void setActivityMapper(ActivityMapper activityMapper) {
this.activityMapper = activityMapper;
}
public UserMapper getUserMapper() {
return userMapper;
}
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
public ActivityBean getNewActivity() {
return newActivity;
}
public void setNewActivity(ActivityBean newActivity) {
this.newActivity = newActivity;
}
public ActivityBean getSelectedActivity() {
return selectedActivity;
}
public void setSelectedActivity(ActivityBean selectedActivity) {
this.selectedActivity = selectedActivity;
}
public List<ActivityBean> getActivities() {
return activities;
}
public void setActivities(List<ActivityBean> activities) {
this.activities = activities;
}
public List<UserBean> getUsers() {
return users;
}
public void setUsers(List<UserBean> users) {
this.users = users;
}
}
My activitybean:
public class ActivityBean implements Serializable {
private Long id = 0L;
private String name;
private String desctription;
private UserBean organiser;
private Calendar startDate;
private Calendar endDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesctription() {
return desctription;
}
public void setDesctription(String desctription) {
this.desctription = desctription;
}
public UserBean getOrganiser() {
return organiser;
}
public void setOrganiser(UserBean organiser) {
this.organiser = organiser;
}
public Calendar getStartDate() {
return startDate;
}
public void setStartDate(Calendar startDate) {
this.startDate = startDate;
}
public Date getStartDateDate() {
if(this.startDate == null) {
return null;
}
return this.endDate.getTime();
}
public void setStartDateDate(Date startDate) {
if(this.startDate == null) {
this.startDate = new GregorianCalendar();
}
this.startDate.setTime(startDate);
}
public String getStartDateString() {
if(this.startDate == null) {
return null;
}
return startDate.get(Calendar.DAY_OF_MONTH) + "/" + startDate.get(Calendar.MONTH) + "/" + startDate.get(Calendar.YEAR) + "";
}
public Calendar getEndDate() {
return endDate;
}
public void setEndDate(Calendar endDate) {
this.endDate = endDate;
}
public Date getEndDateDate() {
if(this.endDate == null) {
return null;
}
return endDate.getTime();
}
public void setEndDateDate(Date endDate) {
if(this.endDate == null) {
this.endDate = new GregorianCalendar();
}
this.endDate.setTime(endDate);
}
public String getEndDateString() {
if(this.endDate == null) {
return null;
}
return endDate.get(Calendar.DAY_OF_MONTH) + "/" + endDate.get(Calendar.MONTH) + "/" + endDate.get(Calendar.YEAR) + "";
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ActivityBean that = (ActivityBean) o;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
return true;
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
My userbean:
public class UserBean {
private Long id;
private String username;
private String firstname;
private String lastname;
private String email;
private String phone;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserBean userBean = (UserBean) o;
if (id != null ? !id.equals(userBean.id) : userBean.id != null) return false;
return true;
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
And the converter used by the selectOneMenu:
#Named
public class userConverter implements Converter{
#Inject
private PlannedActivityController activityController;
#Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
for (UserBean user : activityController.getUsers()) {
if(user.getId().toString().equals(s)) {
return user;
}
}
return null;
}
#Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {
if(o instanceof UserBean) {
UserBean user = (UserBean)o;
return user.getId().toString();
}
return "";
}
}
The problem is here. Look closer. This is invalid EL syntax.
value="#{plannedActivityController.newActivity.organiser}}"
This should however have thrown a PropertyNotWritableException on submit something like this:
javax.el.PropertyNotWritableException: /test.xhtml #25,39 value="#{plannedActivityController.newActivity.organiser}}": Illegal Syntax for Set Operation
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
at javax.faces.component.UIInput.updateModel(UIInput.java:822)
at javax.faces.component.UIInput.processUpdates(UIInput.java:739)
at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1244)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1244)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1223)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
This exception should have been logged to the server log. By default this will however not end up in an error page for the enduser because JSF/PrimeFaces have by default no form of feedback to enduser in case of exceptions which are thrown during ajax requests. You should however be able to see it in actual ajax response body in webbrowser's builtin HTTP traffic monitor.
The JSF utility library OmniFaces offers a FullAjaxExceptionHandler for the very problem of total absence of feedback on exceptions during ajax requests. You may find it useful. When I tried to recreate your problem, I was been presented a clear error page so that I don't need to dig in server log or HTTP traffic monitor for clues.

Resources