Different Result Set While using Criteria vs just Create Query - eclipselink

Manual Method without criteriaQuery
I have used this code to get result set which contains of Thirdparty by using a left join with another table ThirdPartyHasOwner which has two primary keys and is a foreign key itself. Now the below code retrieves the correct result data set.
Query query = emManager.createQuery("SELECT c FROM ThirdParty c LEFT JOIN ThirdPartyHasOwner b ON b.id.third_party_Id = c.id WHERE b.id.ownerId=1");
List<ThirdParty> thirdParties = query.getResultList();
With Criteria Builder and Criteria Query
But When using with the criteria builder and Query the result set gives a wrong dataset. The code is given below So to check whether both above manual query and criteria query gives the same query I added Property <property name="eclipselink.logging.level" value="FINE"/> for which both the above code without criteria query and the below code with criteria query both gave the same query Both the code and console result are given below
CriteriaBuilder cb = emManager.getCriteriaBuilder();
CriteriaQuery<ThirdParty> cq = cb.createQuery(ThirdParty.class);
Root<ThirdParty> a = cq.from(ThirdParty.class);
Join<ThirdParty, ThirdPartyHasOwner> b = a.join("thirdPartyHasOwners", JoinType.LEFT);
ParameterExpression<Integer> balance = cb.parameter(Integer.class);
Path<Integer> path = b.get("id").get("ownerId");
cq.where(cb.gt(path, balance));
cq.select(a);
TypedQuery<ThirdParty> queryS = emManager.createQuery(cq);
List<ThirdParty> results = queryS.setParameter(balance, 1).getResultList();
The Console result (The first one is for the Criteria Query and the second one is for the manual method)
[EL Fine]: sql: 2017-01-04 06:42:44.026--ServerSession(514728045)--Connection(1288428548)--Thread(Thread[http-bio-8080-exec-3,5,main])--SELECT t1.Id, t1.ADDRESS, t1.CONTACTNO, t1.CREATEDDATE, t1.EMAIL, t1.NAME FROM third_party t1 LEFT OUTER JOIN third_party_has_owner t0 ON (t0.THIRD_PARTY_ID = t1.Id) WHERE (t0.owner_id > ?)
bind => [1]
[EL Fine]: sql: 2017-01-04 06:48:26.109--ServerSession(514728045)--Connection(1288428548)--Thread(Thread[http-bio-8080-exec-3,5,main])--SELECT t1.Id, t1.ADDRESS, t1.CONTACTNO, t1.CREATEDDATE, t1.EMAIL, t1.NAME FROM third_party t1 LEFT OUTER JOIN third_party_has_owner t0 ON (t0.THIRD_PARTY_ID = t1.Id) WHERE (t0.owner_id = ?)
bind => [1]
result for both manual and criteria query (result variable has the wrong data which is the result of using criteria query and thirdparties variable has the correct data set which is the result of the manual method)
Last but not least I am using javax.persistence.persistence-api which is eclipselink
This is the overview of the Database tables
Model Class For Third Party
/**
* The persistent class for the third_party database table.
*
*/
#Entity
#Table(name="third_party")
#NamedQuery(name="ThirdParty.findAll", query="SELECT t FROM ThirdParty t")
public class ThirdParty implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="Id")
private int id;
private String address;
private String contactNo;
#Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
private String email;
private String name;
//bi-directional many-to-one association to ThirdPartyHasOwner
#OneToMany(mappedBy="thirdParty")
private List<ThirdPartyHasOwner> thirdPartyHasOwners;
//bi-directional many-to-one association to ThirdSeatAllocation
#OneToMany(mappedBy="thirdParty")
private List<ThirdSeatAllocation> thirdSeatAllocations;
public ThirdParty() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContactNo() {
return this.contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public List<ThirdPartyHasOwner> getThirdPartyHasOwners() {
return this.thirdPartyHasOwners;
}
public void setThirdPartyHasOwners(List<ThirdPartyHasOwner> thirdPartyHasOwners) {
this.thirdPartyHasOwners = thirdPartyHasOwners;
}
public ThirdPartyHasOwner addThirdPartyHasOwner(ThirdPartyHasOwner thirdPartyHasOwner) {
getThirdPartyHasOwners().add(thirdPartyHasOwner);
thirdPartyHasOwner.setThirdParty(this);
return thirdPartyHasOwner;
}
public ThirdPartyHasOwner removeThirdPartyHasOwner(ThirdPartyHasOwner thirdPartyHasOwner) {
getThirdPartyHasOwners().remove(thirdPartyHasOwner);
thirdPartyHasOwner.setThirdParty(null);
return thirdPartyHasOwner;
}
public List<ThirdSeatAllocation> getThirdSeatAllocations() {
return this.thirdSeatAllocations;
}
public void setThirdSeatAllocations(List<ThirdSeatAllocation> thirdSeatAllocations) {
this.thirdSeatAllocations = thirdSeatAllocations;
}
public ThirdSeatAllocation addThirdSeatAllocation(ThirdSeatAllocation thirdSeatAllocation) {
getThirdSeatAllocations().add(thirdSeatAllocation);
thirdSeatAllocation.setThirdParty(this);
return thirdSeatAllocation;
}
public ThirdSeatAllocation removeThirdSeatAllocation(ThirdSeatAllocation thirdSeatAllocation) {
getThirdSeatAllocations().remove(thirdSeatAllocation);
thirdSeatAllocation.setThirdParty(null);
return thirdSeatAllocation;
}
}
Model Class For Third Party has Owner
/**
* The persistent class for the third_party_has_owner database table.
*
*/
#Entity
#Table(name="third_party_has_owner")
#NamedQuery(name="ThirdPartyHasOwner.findAll", query="SELECT t FROM ThirdPartyHasOwner t")
public class ThirdPartyHasOwner implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private ThirdPartyHasOwnerPK id;
#Temporal(TemporalType.DATE)
private Date createdDate;
//bi-directional many-to-one association to Owner
#ManyToOne
private Owner owner;
//bi-directional many-to-one association to ThirdParty
#ManyToOne
#JoinColumn(name="third_party_Id")
private ThirdParty thirdParty;
public ThirdPartyHasOwner() {
}
public ThirdPartyHasOwnerPK getId() {
return this.id;
}
public void setId(ThirdPartyHasOwnerPK id) {
this.id = id;
}
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Owner getOwner() {
return this.owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
public ThirdParty getThirdParty() {
return this.thirdParty;
}
public void setThirdParty(ThirdParty thirdParty) {
this.thirdParty = thirdParty;
}
}
So Did I do something wrong with the criteria query or is it some weird bug?

Though the log was fine still I have used a different method which gives the different data set.
Before Code
CriteriaBuilder cb = emManager.getCriteriaBuilder();
CriteriaQuery<ThirdParty> cq = cb.createQuery(ThirdParty.class);
Root<ThirdParty> a = cq.from(ThirdParty.class);
Join<ThirdParty, ThirdPartyHasOwner> b = a.join("thirdPartyHasOwners", JoinType.LEFT);
ParameterExpression<Integer> balance = cb.parameter(Integer.class);
Path<Integer> path = b.get("id").get("ownerId");
cq.where(cb.gt(path, balance));
cq.select(a);
TypedQuery<ThirdParty> queryS = emManager.createQuery(cq);
List<ThirdParty> results = queryS.setParameter(balance, 1).getResultList();
After Code
CriteriaBuilder cb = emManager.getCriteriaBuilder();
CriteriaQuery<ThirdParty> cq = cb.createQuery(ThirdParty.class);
Root<ThirdParty> a = cq.from(ThirdParty.class);
Join<ThirdParty, ThirdPartyHasOwner> b = a.join("thirdPartyHasOwners", JoinType.LEFT);
ParameterExpression<Integer> balance = cb.parameter(Integer.class);
cq.where(cb.equal( b.get("id").get("ownerId"),balance));
cq.select(a);
TypedQuery<ThirdParty> queryS = emManager.createQuery(cq);
List<ThirdParty> results = queryS.setParameter(balance, 1).getResultList();
The code which is being changed is cq.where(cb.gt(path, balance)); to cq.where(cb.equal( b.get("id").get("ownerId"),balance)); for criteria builder equal is used here is equal to Where b.owner_id = balance balance is a parameter

Related

#Transactional doesn't update records using HQL or SQL

I am using transactional annotation in order to enable auto-commit in Oracle DB.
When I use criteria to update records, I get the record updated successfully. But when I use HQL or SQL, in the console the query is printed but doesn't execute
This is Notification DAO
#Repository("SystemUserNotificationDao")
public class SystemUserNotificationDaoImpl extends AbstractDao<BigDecimal, SystemUserNotification> implements SystemUserNotificationDao {
#Override
public Number setNotificationsAsSeen() {
Query query = createHqlQuery("update SystemUserNotification set seen = 1 where seen = 0");
return (Number)query.executeUpdate();
}
}
This is the service
Service("SystemUserNotificationService")
#Transactional
public class SystemUserNotificationServiceImpl implements SystemUserNotificationService {
#Autowired
SystemUserNotificationDao systemUserNotificationDao;
#Override
public Number setNotificationsAsSeen() {
return systemUserNotificationDao.setNotificationsAsSeen();
}
}
This is the AbstractDao
public abstract class AbstractDao<PK extends Serializable, T> {
private final Class<T> persistentClass;
#SuppressWarnings("unchecked")
public AbstractDao() {
this.persistentClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
#Autowired
private SessionFactory sessionFactory;
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
public T getByKey(PK key) {
return (T) getSession().get(persistentClass, key);
}
public void persist(T entity) {
getSession().persist(entity);
}
public void update(T entity) {
getSession().update(entity);
}
public void saveOrUpdate(T entity) {
getSession().saveOrUpdate(entity);
}
public void delete(T entity) {
getSession().delete(entity);
}
protected Criteria createEntityCriteria() {
return getSession().createCriteria(persistentClass);
}
protected SQLQuery createSqlQuery(String query) {
return getSession().createSQLQuery(query);
}
protected Query createHqlQuery(String query) {
return getSession().createQuery(query);
}
}
I tried to add transaction.begin and commit but it gives me nested transactions not supported
#Override
public Number setNotificationsAsSeen() {
// Query query = createHqlQuery("update SystemUserNotification set seen = 1 where seen = 0");
Transaction tx = getSession().beginTransaction();
Query query = getSession().createQuery("update SystemUserNotification set seen = 1 where seen = 0");
Number n = (Number)query.executeUpdate();
tx.commit();
return n;
}
The issue was with SQL developer tool. there were uncommitted changes, I closed the dev tool and the update query worked fine

Embedded Neo4j delete node and Lucene legacy indexing - node_auto_indexing out of sync issue

I'm trying to delete node with fields in node_auto_indexing.
When I try to delete node using repository.delete(id).
Right after that I'm trying to get deleted Node by its id and I get following exception:
java.lang.IllegalStateException: This index (Index[__rel_types__,Relationship]) has been marked as deleted in this transaction
at org.neo4j.index.impl.lucene.LuceneTransaction$DeletedTxDataBoth.illegalStateException(LuceneTransaction.java:475)
at org.neo4j.index.impl.lucene.LuceneTransaction$DeletedTxDataBoth.removed(LuceneTransaction.java:470)
at org.neo4j.index.impl.lucene.LuceneTransaction.remove(LuceneTransaction.java:112)
at org.neo4j.index.impl.lucene.LuceneXaConnection.remove(LuceneXaConnection.java:116)
at org.neo4j.index.impl.lucene.LuceneIndex.remove(LuceneIndex.java:215)
at org.springframework.data.neo4j.support.typerepresentation.AbstractIndexBasedTypeRepresentationStrategy.remove(AbstractIndexBasedTypeRepresentationStrategy.java:113)
at org.springframework.data.neo4j.support.typerepresentation.AbstractIndexBasedTypeRepresentationStrategy.preEntityRemoval(AbstractIndexBasedTypeRepresentationStrategy.java:100)
at org.springframework.data.neo4j.support.mapping.EntityRemover.removeRelationship(EntityRemover.java:63)
at org.springframework.data.neo4j.support.mapping.EntityRemover.removeNode(EntityRemover.java:51)
at org.springframework.data.neo4j.support.mapping.EntityRemover.removeNodeEntity(EntityRemover.java:45)
at org.springframework.data.neo4j.support.mapping.EntityRemover.remove(EntityRemover.java:85)
at org.springframework.data.neo4j.support.Neo4jTemplate.delete(Neo4jTemplate.java:267)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.delete(AbstractGraphRepository.java:276)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.delete(AbstractGraphRepository.java:282)
Also, when I'm trying to delete node via Cypher query
#Query("MATCH ()-[r]-(p:Product) WHERE id(p) = {productId} DELETE r, p")
void deleteProduct(#Param("productId") Long productId);
I'm getting another exception after looking this deleted Node by its Id:
java.lang.IllegalStateException: No primary SDN label exists .. (i.e one starting with _)
at org.springframework.data.neo4j.support.typerepresentation.LabelBasedNodeTypeRepresentationStrategy.readAliasFrom(LabelBasedNodeTypeRepresentationStrategy.java:126)
at org.springframework.data.neo4j.support.typerepresentation.LabelBasedNodeTypeRepresentationStrategy.readAliasFrom(LabelBasedNodeTypeRepresentationStrategy.java:39)
at org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor.readAliasFrom(TRSTypeAliasAccessor.java:36)
at org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor.readAliasFrom(TRSTypeAliasAccessor.java:26)
at org.springframework.data.convert.DefaultTypeMapper.readType(DefaultTypeMapper.java:102)
at org.springframework.data.convert.DefaultTypeMapper.getDefaultedTypeToBeUsed(DefaultTypeMapper.java:165)
at org.springframework.data.convert.DefaultTypeMapper.readType(DefaultTypeMapper.java:142)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:78)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
at org.springframework.data.neo4j.support.Neo4jTemplate.createEntityFromState(Neo4jTemplate.java:224)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.createEntity(AbstractGraphRepository.java:62)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.findOne(AbstractGraphRepository.java:127)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.delete(AbstractGraphRepository.java:282)
How to correctly delete node that participates in Lucene Legacy Indexing node_auto_indexing ? How to remove this Node from Lucene index ?
UPDATED:
This is my Neo4jConfig:
#Configuration
#EnableNeo4jRepositories(basePackages = "com.example")
#EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration implements BeanFactoryAware {
#Resource
private Environment environment;
private BeanFactory beanFactory;
public Neo4jConfig() {
setBasePackage("com.example");
}
#Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService() {
GraphDatabaseService graphDb = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder("target/example-test-db")
.setConfig(GraphDatabaseSettings.node_keys_indexable, "name,description")
.setConfig(GraphDatabaseSettings.node_auto_indexing, "true")
.newGraphDatabase();
return graphDb;
}
/**
* Hook into the application lifecycle and register listeners that perform
* behaviour across types of entities during this life cycle
*
*/
#Bean
protected ApplicationListener<BeforeSaveEvent<BaseEntity>> beforeSaveEventApplicationListener() {
return new ApplicationListener<BeforeSaveEvent<BaseEntity>>() {
#Override
public void onApplicationEvent(BeforeSaveEvent<BaseEntity> event) {
BaseEntity entity = event.getEntity();
if (entity.getCreateDate() == null) {
entity.setCreateDate(new Date());
} else {
entity.setUpdateDate(new Date());
}
}
};
}
#Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
}
Base entity for entities in the project:
public class BaseEntity {
private Date createDate;
private Date updateDate;
public BaseEntity() {
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
}
and the Vote entity that I tried to delete:
#NodeEntity
public class Vote extends BaseEntity {
private static final String VOTED_ON = "VOTED_ON";
private final static String VOTED_FOR = "VOTED_FOR";
private static final String CREATED_BY = "CREATED_BY";
#GraphId
private Long id;
#RelatedTo(type = VOTED_FOR, direction = Direction.OUTGOING)
private Decision decision;
#RelatedTo(type = VOTED_ON, direction = Direction.OUTGOING)
private Criterion criterion;
#RelatedTo(type = CREATED_BY, direction = Direction.OUTGOING)
private User author;
private double weight;
private String description;
public Vote() {
}
public Vote(Decision decision, Criterion criterion, User author, double weight, String description) {
this.decision = decision;
this.criterion = criterion;
this.author = author;
this.weight = weight;
this.description = description;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Decision getDecision() {
return decision;
}
public void setDecision(Decision decision) {
this.decision = decision;
}
public Criterion getCriterion() {
return criterion;
}
public void setCriterion(Criterion criterion) {
this.criterion = criterion;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Vote vote = (Vote) o;
if (id == null)
return super.equals(o);
return id.equals(vote.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
Thanks to #MichaelHunger and Neo4j this issue has been fixed in Neo4j 2.2.2 and SDN 3.4.0.M1

PersistenceException: ERROR executing DML bindLog when Updating an Object

Good day! I have two objects: Tag and RelatedTag. The Tag can have many RelatedTags (which is also a Tag). Saving the Tag with its related tags works fine. But when I update the Tag, it has an error saying
[PersistenceException: ERROR executing DML bindLog[] error[Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.RELATED_TAG(ID)"; SQL statement:\n insert into related_tag (id, tag_id, relationship, related_notes) values (?,?,?,?) [23505-172]]]
Here is Tag model:
package models;
import java.util.*;
import javax.persistence.*;
import javax.validation.*;
import play.data.Form;
import play.data.validation.Constraints.*;
import play.db.ebean.*;
import play.db.ebean.Model.Finder;
import scala.Int;
#Entity
public class Tag extends Model{
#Id
private int id;
#Required
#MaxLength(value=100)
private String name;
#MaxLength(value=200)
private String notes;
#OneToMany(cascade=CascadeType.ALL)
public List<RelatedTag> relatedTags = new ArrayList<RelatedTag>();
public static Finder<Integer, Tag> find = new Finder(Int.class, Tag.class);
public Tag() {
}
public Tag(String name, String notes){
this.name = name;
this.notes = notes;
}
public Tag(int id, String name, String notes, List<RelatedTag> relatedTags) {
this.id = id;
this.name = name;
this.notes = notes;
this.relatedTags = relatedTags;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public List<RelatedTag> getRelatedTags() {
return relatedTags;
}
public void setRelatedTags(List<RelatedTag> relatedTags) {
this.relatedTags = relatedTags;
}
public static List<Tag> all() {
return find.all();
}
public static void create(Tag tag){
tag.save();
}
public static void delete(int id){
find.ref(id).delete();
}
public static void update(int id, Tag tag) {
tag.update(id); // updates this entity, by specifying the entity ID
}
public static boolean exists(Tag newTag) {
for(Tag allTags : Tag.find.all()) {
if(allTags.getName().equals(newTag.getName()))
return true;
}
return false;
}
}
And here is the RelatedTag model:
package models;
import java.util.*;
import javax.persistence.*;
import javax.validation.*;
import play.data.Form;
import play.data.validation.Constraints.*;
import play.db.ebean.*;
import play.db.ebean.Model.Finder;
import scala.Int;
#Entity
public class RelatedTag extends Model {
#Id
private int id;
private String relationship;
private String relatedNotes;
public RelatedTag() {}
public RelatedTag(int id, String relationship, String relatedNotes) {
this.id = id;
this.relationship = relationship;
this.relatedNotes = relatedNotes;
}
public void setId(int id){
this.id = id;
}
public void setRelationship(String relationship){
this.relationship = relationship;
}
public void setRelatedNotes(String relatedNotes) {
this.relatedNotes = relatedNotes;
}
public int getId(){
return id;
}
public String getRelationship(){
return relationship;
}
public String getRelatedNotes() {
return relatedNotes;
}
public static boolean exists(String tagRelated) {
for(Tag tag : Tag.find.all()) {
if(tagRelated.equals(tag.getName()))
return true;
}
return false;
}
public static RelatedTag findByLabel(String tagRelated, String relation, String relatedNotes) {
RelatedTag relatedTag = null;
for(Tag tag : Tag.find.all()) {
if(tagRelated.equals(tag.getName())) {
relatedTag = new RelatedTag(tag.getId(), relation, relatedNotes);
}
}
return relatedTag;
}
public static Tag findTag(int id) {
for(Tag tag : Tag.find.all()) {
if(id == tag.getId())
return tag;
}
return null;
}
}
When I run this (in which I update a Tag), the error happens.
private static void reciprocate(Tag tag) {
List<Tag> peers = new ArrayList<Tag>();
for (RelatedTag rt : tag.getRelatedTags()) {
if(rt.getRelationship().equals("peer"))
peers.add(RelatedTag.findTag(rt.getId()));
}
for(RelatedTag rt : tag.getRelatedTags()) {
int relTemp = 0;
String relation = new String();
if (rt.getRelationship().equals("parent"))
relTemp = 1;
if (rt.getRelationship().equals("child"))
relTemp = 2;
if (rt.getRelationship().equals("peer"))
relTemp = 3;
switch(relTemp) {
case 1: relation = "child"; break;
case 2: relation = "parent"; break;
case 3: relation = "peer"; break;
}
Tag related = new Tag();
related = Tag.find.byId(RelatedTag.findTag(rt.getId()).getId());
List<RelatedTag> available = new ArrayList<RelatedTag>();
List<String> availableName = new ArrayList<String>();
for (RelatedTag rt2 : related.getRelatedTags()) {
availableName.add(RelatedTag.findTag(rt2.getId()).getName());
}
if(availableName.contains(tag.getName())) {
for(RelatedTag rt2 : related.getRelatedTags()) {
if(!RelatedTag.findTag(rt2.getId()).getName().equals(tag.getName())) {
available.add(rt2);
}
}
}
available.add(RelatedTag.findByLabel(
tag.getName(), relation,
rt.getRelatedNotes()));
related.setRelatedTags(available);
related.update(related.getId()); //HERE
}
}
Please help me figure this out. After the first rt has been iterated, there goes the error but it saves its related tag. Thank you very much.
Your method RelatedTag#findByLabel always creates new RelatedTags with the IDs of the Tag class; if you have 2 related tags for the same tag, it will produce 2 related tags with the same ID.
Look into #GeneratedValue and EntityManager#createQuery.

How to use hibernate lucene search for entity which have many to one relation

I am using Hibernate lucene for searching. Now I want to search with an entity which has a many to one relation
I have two class one is catalogueBase and another one is Subject, here subject has a many-to-one relation (it is one sided relation)
catalogueBase.java class :
#Indexed
#JsonAutoDetect
#Entity
#Table(name="catalogueBase")
public class CatalogueBase extends BaseObject implements Serializable {
// some entities
// ...
private Subject subject;
// setter and get methods
// ...
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
#ManyToOne
#NotFound(action= NotFoundAction.IGNORE)
#JoinColumn(name = "subject1", insertable = true, updatable=true, nullable = true)
#JsonProperty
public Subject getSubject() {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
}
Subject.java (what ever i want to search regarding subject it will be stored in description column) :
#Indexed
#JsonAutoDetect
#Entity
#Table(name="subject")
public class Subject implements java.io.Serializable {
private String description;
// ...
#Column(name = "subjectname", nullable = false, length = 150)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
// ....
}
this is my DAO method :
private List<CatalogueBase> searchTitle(String queryString) throws InterruptedException {
Session session = getSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
org.hibernate.Query fullTextQuery = null;
List<CatalogueBase> resultList = null;
try{
QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(CatalogueBase.class).get();
org.apache.lucene.search.Query luceneQuery = queryBuilder.keyword().onFields("title","subject").matching(queryString).createQuery();
fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, CatalogueBase.class);
List<CatalogueBase> contactList = fullTextQuery.list();
resultList = new ArrayList<CatalogueBase>();;
for (CatalogueBase catalogueBase : contactList) {
catalogueBase.setNoOfCopiesBooks(getCopydetailsCount(catalogueBase.getId()));
catalogueBase.setIssuedCount(getIssuedCount(catalogueBase.getId()));
resultList.add(catalogueBase);
}
} catch(Exception e) {
e.printStackTrace();
}
return resultList;
}
But it's giving an error like: SearchException: Unable to find field subject in com.easylib.elibrary.model.CatalogueBase
And I did something like this post, but error was the same.
I got solution.
I will just post code...
#Indexed // must
#JsonAutoDetect
#Entity
#Table(name="subject")
public class Subject implements java.io.Serializable {
private String description;
#ContainedIn // must
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
#Column(name = "subjectname", nullable = false, length = 150)
public String getDescription() {
return this.description;
}
}
In catalogue:
#ManyToOne
#NotFound(action= NotFoundAction.IGNORE)
#JoinColumn(name = "subject1", insertable = true, updatable=true, nullable = true)
#JsonProperty
#IndexedEmbedded // must
public Subject getSubject() {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
And in the DAO, it must be:
org.apache.lucene.search.Query luceneQuery = queryBuilder.keyword().onFields("subject.description").matching(queryString).createQuery();

Why are the foreign keys in ejb declared as objects(entities)?

I'am developing a java web EE application using EJB, JPA and netbeans. I've created a table with sql named users for registration and login and another table named prescripts which has 3 foreign keys refering to the primary key idusers of users(docid, pharmid, patid).
I also created with net beans entity bean named users and a session bean named UsersFacade and for prescripts an entity bean: prescripts and session bean: PrescriptsFacade.
My question is this:
Why in users ejb all variables(columns) are declared as they are(string for string, integer for integer etc) and in prescripts are declared as users?
//users.java
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idusers")
private Integer idusers;
#Column(name = "user_type")
private String userType;
#Column(name = "name")
private String name;
#Column(name = "nickname")
private String nickname;
//prescripts.java
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idprescripts")
private Integer idprescripts;
#Column(name = "data")
private String data;
#JoinColumn(name = "pharm_id", referencedColumnName = "idusers")
#ManyToOne
private Users users;
#JoinColumn(name = "doc_id", referencedColumnName = "idusers")
#ManyToOne
private Users users1;
#JoinColumn(name = "pat_id", referencedColumnName = "idusers")
#ManyToOne
private Users users2;
For users i use this code in a servlet to insert a row in sql base:
Users currentUsers;
currentUsers = new Users();
String Type = request.getParameter("user_type");
String Name = request.getParameter("name");
String Nickname = request.getParameter("nickname");
currentUsers.setUserType(Type);
currentUsers.setName(Name);
currentUsers.setNickname(Nickname);
UsersFacade.create(currentUsers);
How am i supposed to insert a row in prescripts this way?
This doesn't work(it shows error null pointer exception):
currentPresc = new Prescripts();
String PatID = request.getParameter("pat_id");
String DocID = request.getParameter("doc_id");
String PharmID = request.getParameter("pharm_id");
String Data = request.getParameter("data");
int patid = Integer.parseInt(PatID);
int docid = Integer.parseInt(DocID);
int pharmid = Integer.parseInt(PharmID);
currentUsers = UsersFacade.find(patid);
currentPresc.setUsers(currentUsers);
currentUsers = UsersFacade.find(docid);
currentPresc.setUsers1(currentUsers);
currentUsers = UsersFacade.find(pharmid);
currentPresc.setUsers2(currentUsers);
currentPresc.setData(Data);
PrescriptsFacade.create(currentPresc);
I skipped the set and get methods and some variables for simplifying reasons. Please any help is really very appreciated, i am stucked with this 2 weeks now :'(
I send you the whole classes of users and prescripts:
Prescripts.java
package entities;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
#Entity
#Table(name = "prescripts")
#NamedQueries({
#NamedQuery(name = "Prescripts.findAll", query = "SELECT p FROM Prescripts p"),
#NamedQuery(name = "Prescripts.findByIdprescripts", query = "SELECT p FROM Prescripts p WHERE p.idprescripts = :idprescripts"),
#NamedQuery(name = "Prescripts.findByData", query = "SELECT p FROM Prescripts p WHERE p.presc = :presc")})
public class Prescripts implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idprescripts")
private Integer idprescripts;
#JoinColumn(name = "doc_id", referencedColumnName = "idusers")
#ManyToOne
private Users doc_id;
#JoinColumn(name = "pat_id", referencedColumnName = "idusers")
#ManyToOne
private Users pat_id;
#JoinColumn(name = "pharm_id", referencedColumnName = "idusers")
#ManyToOne
private Users pharm_id;
#Column(name = "presc")
private String presc;
public Prescripts() {
}
public Prescripts(Users pat_id, Users pharm_id, Users doc_id, String presc) {
this.pharm_id = pharm_id;
this.doc_id = doc_id;
this.pat_id = pat_id;
this.presc = presc;
}
public Integer getIdprescripts() {
return idprescripts;
}
public void setIdprescripts(Integer idprescripts) {
this.idprescripts = idprescripts;
}
public String getPresc() {
return presc;
}
public void setPresc(String presc) {
this.presc = presc;
}
public Users getPharmId() {
return pharm_id;
}
public void setPharmId(Users pharm_id) {
this.pharm_id = pharm_id;
}
public Users getDocId() {
return doc_id;
}
public void setDocId(Users doc_id) {
this.doc_id = doc_id;
}
public Users getPatId() {
return pat_id;
}
public void setPatId(Users pat_id) {
this.pat_id = pat_id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idprescripts != null ? idprescripts.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Prescripts)) {
return false;
}
Prescripts other = (Prescripts) object;
if ((this.idprescripts == null && other.idprescripts != null) || (this.idprescripts != null && !this.idprescripts.equals(other.idprescripts))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entities.Prescripts[idprescripts=" + idprescripts + "]";
}
}
Users.java
package entities;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlTransient;
#Entity
#Table(name = "users")
#NamedQueries({
#NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
#NamedQuery(name = "Users.findByIdusers", query = "SELECT u FROM Users u WHERE u.idusers = :idusers"),
#NamedQuery(name = "Users.findByUserType", query = "SELECT u FROM Users u WHERE u.userType = :userType"),
#NamedQuery(name = "Users.findByNickname", query = "SELECT u FROM Users u WHERE u.nickname = :nickname"),
#NamedQuery(name = "Users.findByName", query = "SELECT u FROM Users u WHERE u.name = :name"),
#NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password"),
#NamedQuery(name = "Users.findByEmail", query = "SELECT u FROM Users u WHERE u.email = :email"),
#NamedQuery(name = "Users.findByCity", query = "SELECT u FROM Users u WHERE u.city = :city"),
#NamedQuery(name = "Users.findByStreet", query = "SELECT u FROM Users u WHERE u.street = :street"),
#NamedQuery(name = "Users.findByAt", query = "SELECT u FROM Users u WHERE u.at = :at"),
#NamedQuery(name = "Users.findByAmka", query = "SELECT u FROM Users u WHERE u.amka = :amka"),
#NamedQuery(name = "Users.findByAfm", query = "SELECT u FROM Users u WHERE u.afm = :afm"),
#NamedQuery(name = "Users.findByVerify", query = "SELECT u FROM Users u WHERE u.verify = :verify")})
public class Users implements Serializable {
#OneToMany(mappedBy = "pat_id")
private List<Prescripts> prescriptsList;
#OneToMany(mappedBy = "doc_id")
private List<Prescripts> prescriptsList1;
#OneToMany(mappedBy = "pharm_id")
private List<Prescripts> prescriptsList2;
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idusers")
private Integer idusers;
#Column(name = "user_type")
private String userType;
#Column(name = "name")
private String name;
#Column(name = "nickname")
private String nickname;
#Column(name = "password")
private String password;
#Column(name = "email")
private String email;
#Column(name = "city")
private String city;
#Column(name = "street")
private String street;
#Column(name = "AT")
private String at;
#Column(name = "AMKA")
private String amka;
#Column(name = "AFM")
private String afm;
#Column(name = "verify")
private Boolean verify;
public Users() {
}
public Users( String userType,String name,String nickname, String password, String email, String city, String street, String at,
String amka, String afm, Boolean verify)
{
this.userType= userType;
this.name= name;
this.nickname= nickname;
this.password= password;
this.email = email;
this.city = city;
this.street = street;
this.at = at;
this.amka = amka;
this.afm = afm;
this.verify=verify;
}
public Integer getIdusers() {
return idusers;
}
public void setIdusers(Integer idusers) {
this.idusers = idusers;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getAt() {
return at;
}
public void setAt(String at) {
this.at = at;
}
public String getAmka() {
return amka;
}
public void setAmka(String amka) {
this.amka = amka;
}
public String getAfm() {
return afm;
}
public void setAfm(String afm) {
this.afm = afm;
}
public Boolean getVerify() {
return verify;
}
public void setVerify(Boolean verify) {
this.verify = verify;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idusers != null ? idusers.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Users)) {
return false;
}
Users other = (Users) object;
if ((this.idusers == null && other.idusers != null) || (this.idusers != null && !this.idusers.equals(other.idusers))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entities.Users[idusers=" + idusers + "]";
}
public List<Prescripts> getPrescriptsList() {
return prescriptsList;
}
public void setPrescriptsList(List<Prescripts> prescriptsList) {
this.prescriptsList = prescriptsList;
}
public List<Prescripts> getPrescriptsList1() {
return prescriptsList1;
}
public void setPrescriptsList1(List<Prescripts> prescriptsList1) {
this.prescriptsList1 = prescriptsList1;
}
public List<Prescripts> getPrescriptsList2() {
return prescriptsList2;
}
public void setPrescriptsList2(List<Prescripts> prescriptsList2) {
this.prescriptsList2 = prescriptsList2;
}
}
The main question seems to be why variables in the User-class is declared as Integer, but the "user_id-variable" in Prescript is declared as User.
This is simply the way EJB3 works. You are thinking to much in terms of sql and relational databases. You define the primary key of tables (e.g. Users.idusers) as if it was a column, but references to other objects (entities, to be precise) are defined using the natural object. Therefore the Prescripts.users is declared as a Users-object. The EJB platform will take care of transforming this into a database column (in this case probably named users_idusers), with the correct type (in this case Integer), but this is taken care of and you shouldn't need to care about that.
You should go through a EJB3 tutorial or two - there are plenty of these, and make sure you complete the tutorials. You seemed to have missed some of the basics. Also note that your code could have been much simpler. The "#Column"-annotations are usually not needed, mapped_by is usually not needed, column-names ditto, etc. Also use singular names (User instead of Users). The common standard for primarykeys is simply #Id Long id, making it easy to remember the name of the primary key for all entities (but some prefer distinct names).
To answer your actual problem we would need more information, including what is on TestServlet.java line 233. Your code seems more or less correct, but it is hard for others to verify that. Finding the Users-object from EntityManger/facade and then setting it into the Prescipts-object is the correct way to do it.
In java, relations between entities (in a entity-relationship model) is represented as references to objects, (one-to-one) or lists of references to objects (one-to-many)
A relational database implements relations between entities (rows in tables) as foreign keys, that matches the primary key for a row in another table.
(The word "relational" in a "relational database" does actually just mean that the columns (tuples) in a table is related to each other...The foreign key stuff is an addition.)
I generally considered smart to start with a proper entity-relationshop model before designing database tables all willy nilly...