SchoolViewModel.java
public class SchoolViewModel {
private String state;
private String city;
private String instituteType;
//getter and setter
}
InstituteType.java
#Entity
#Table(name="REF_INSTITUTE_TYPE")
public class InstituteType implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name="ID")
private Integer id;
#Column(name="INSTITUTE_TYPE")
private String instituteType;
public Integer getId() {
return id;
}
#ManyToMany(mappedBy="instituteType")
private Set<SchoolDetail> schoolDetail =new HashSet<SchoolDetail>();
//getter and setter
}
Board.java
#Entity
#Table(name="REF_BOARD")
public class Board implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name="ID")
private Integer id;
#Column(name="BAORD")
private String board;
#ManyToMany(mappedBy="board")
private Set<SchoolDetail> schoolDetail =new HashSet<SchoolDetail>();
//getter and setter
}
SchoolDetail.java
#Entity
#Table(name="SCHOOL_DETAIL")
public class SchoolDetail implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name="id")
private int id;
#Column(name="name")
private String name;
#Column(name="state")
private String state;
#Column(name="city")
private String city;
#ManyToMany
#JoinTable(name="SCHOOL_INSTITUTE_TYPE",
joinColumns={#JoinColumn(name="SCHOOL_ID")},
inverseJoinColumns={#JoinColumn(name="INSTITUTE_TYPE_ID")}
)
private Set<InstituteType> instituteType=new HashSet<InstituteType>();
#ManyToMany
#JoinTable(name="SCHOOL_BOARD",
joinColumns={#JoinColumn(name="SCHOOL_ID")},
inverseJoinColumns={#JoinColumn(name="BOARD_ID")}
)
private Set<Board> board=new HashSet<Board>();
//getter and setter
}
Main.java
public class SchoolBoard {
public static void main(String[] args) {
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");
SessionFactory sessionFactory=cfg.buildSessionFactory();
Session session=sessionFactory.openSession();
try{
SchoolViewModel svm=new SchoolViewModel();
svm.setState("Maharastra");
svm.setCity("Pune");
svm.setInstituteType("college");
SchoolDetail school=new SchoolDetail();
school.setState(svm.getState());
school.setCity(svm.getCity());
InstituteType instituteType=new InstituteType();
instituteType.setInstituteType(svm.getInstituteType());
Board board=new Board();
board.setBoard("STATE");
Example schoolExample=Example.create(school).ignoreCase().enableLike().excludeZeroes();
Example instituteTypeExample=Example.create(instituteType).ignoreCase().enableLike().excludeZeroes();
Example boardExample=Example.create(board).ignoreCase().enableLike().excludeZeroes();
Criteria criteria=session.createCriteria(SchoolDetail.class,"schoolDetail");
criteria.createAlias("schoolDetail.instituteType", "instituteType");
criteria.createAlias("schoolDetail.board", "board");
criteria.add(schoolExample);
criteria.add(instituteTypeExample);
criteria.add(boardExample);
Line - 48 List<SchoolDetail> schoolList=criteria.list();
}finally{
session.close();
sessionFactory.close();
}
}
}
Exception is :
Exception in thread "main" org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.util.Set<com.mypack.model.Board> com.mypack.model.SchoolDetail.board] by reflection for persistent property [com.mypack.model.SchoolDetail#board] : com.mypack.model.InstituteType#f555e7
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:71)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValues(AbstractEntityTuplizer.java:506)
at org.hibernate.tuple.entity.PojoEntityTuplizer.getPropertyValues(PojoEntityTuplizer.java:215)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValues(AbstractEntityPersister.java:4626)
at org.hibernate.criterion.Example.toSqlString(Example.java:190)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:400)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:106)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:75)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:80)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1849)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:365)
at com.mypack.dao.SchoolBoard.main(SchoolBoard.java:48)
Caused by: java.lang.IllegalArgumentException: Can not set java.util.Set field com.mypack.model.SchoolDetail.board to com.mypack.model.InstituteType
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:387)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:67)
... 11 more
Description : SchoolViewModel is pojo class which will carry data from front end. The screen is Search screen and contains Refine your search just like any e-commerce website where you can filter or narrow down your search. Based on user selection database will retrieve data from database. For this I have implement query by example in hibernate. But while multiple examples in criteria it throws exception.
Related
I am having an issue fetching data from redis in my Java spring boot application
I created the following classes
public interface ArticlesRepository extends CrudRepository<Articles, String> {
}
#RedisHash("Articles")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Articles implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private long timestamp;
private ArticlesData articles;
}
#RedisHash("ArticlesData")
#JsonIgnoreProperties(ignoreUnknown = true)
public class ArticlesData implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String continuation;
private ArrayList<ArticleInfo> articles;
}
#RedisHash("ArticleInfo")
#JsonIgnoreProperties(ignoreUnknown = true)
public class ArticleInfo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String title;
private String linkToArticle;
private long publishedDate;
}
Everything appears to work as expected when I save an instance of Articles
Articles articles = new Articles(id, timestamp, articlesData);
articlesRepository.save(articles);
However, when I attempt to retrieve that object from redis something weird happens
Articles articles = articlesRepository.findOne(redisArticleId);
All the fields in the object (id and timestamp) are set correctly except for ArticlesData which always returns null.
System.out.println(articles.getId()); ==> WAPCO:
System.out.println(articles.getTimestamp()); ==> 1530049920
System.out.println(articles.getArticles()); ==> null
Anyone have any ideas on what I might be doing wrong?
I'm developing a project in JSF, and I'm trying to persist this Entity below, but I'm receiving a error message. Before I created the relationship, the Conta class was persisting correctly, but with the Many To One with Transacao, I can't.
This is the Transacao class:
#Id
#GeneratedValue
private long id;
private Conta contaOrigem;
private String agenciaDestino;
private String contaDestino;
private String cpfDestino;
...
This is the Conta class:
public class Conta {
#EmbeddedId
private DadosConta contaUsuario = new DadosConta();
#NotEmpty(message="Senha não pode estar em branco")
private String senha;
#NotEmpty(message="Selecione uma opção")
private String tipoConta;
private double saldo;
private Usuario usuario = new Usuario();
#OneToMany(mappedBy="contaOrigem", fetch = FetchType.LAZY)
private List<Transacao> transacoes = new ArrayList<>();
...
And the DadosConta (Embedded ID class):
#Embeddable
public class DadosConta implements Serializable {
private static final long serialVersionUID = -7021727065659352073L;
#NotEmpty
private String agencia;
#NotEmpty
private String conta;
...
And finally, this is the error:
Foreign key (FK_8k5jlptboiq6xm4oopg9jnh2l:Transacao [contaOrigem])) must have same number of columns as the referenced primary key (conta [agencia,conta])
I know that the error message is "explicit", but I don't know how can I persist this Many to One relationship with EmbeddedId, is there any workaround?
Thanks a lot.
Try this in your Transacao class to complete the bi-directional join.
#ManyToOne
#JoinColumns({#JoinColumn(name = "agencia"), #JoinColumn(name = "conta")})
private Conta contaOrigem;
I have two pojo classes named OwnerDetails & VehicleDetails, which are show below
#Entity
public class OwnerDetails implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name="Owner_id")
private int id;
#Column(name="owner_name")
private String ownerName;
#Column(name="email_id")
private String email;
#Column(name="mobile")
private String mobile;
#Column(name="land_line")
private String phone;
#Column(name="Mailing_Address")
private String mailing_address;
#OneToMany(mappedBy="ownerDetails", cascade=CascadeType.ALL)
private Set<VehicleDetails> vehicleDetails;
// getter & Setter...
}
#Entity
public class VehicleDetails implements Serializable{
private static final long serialVersionUID = 1L;
#Id
private int v_id;
#Column(name="TYPE")
private String type;
#Column(name="AC_OR_NON_AC")
private boolean aircondition;
#Column(name="SEATING_CAPACITY")
private int seatingCapacity;
#Column(name="FUEL_TYPE")
private String fuel_type;
#Column(name="Reg_number")
private String reg_number;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="Owner_id")
private OwnerDetails ownerDetails;
// getter & Setter....
}
And the main program is
public static void main(String[] args) throws InterruptedException {
SessionFactory sf=getSessionFactory();
Session session=sf.getCurrentSession();
Transaction txn=session.beginTransaction();
OwnerDetails own=(OwnerDetails)session.get(OwnerDetails.class, 1);
Set<VehicleDetails> vhSet=new HashSet<VehicleDetails>();
VehicleDetails vh=new VehicleDetails();
vh.setAircondition(true);
vh.setFuel_type("DIESEL");
vh.setReg_number("TN32 AA 5555");
vh.setSeatingCapacity(12);
vh.setV_id(11);
vh.setType("INNOVA");
vh.setOwnerDetails(own);
vhSet.add(vh);
own.setVehicleDetails(vhSet);
session.saveOrUpdate(own);
txn.commit();
}
The issue I am having happens after ownerdetails and vehicledetails are saved successfully without any issue.
But I need to add one more vihicledetails with same ownerdetails. It updates current vihicledetails instance with ownerid and existing row in vihicledetails are updated with null ownerid.
please find the below tables.
Looks like the statement own.setVehicleDetails(vhSet); is causing the vehicleDetails set to be replaced with just the new one. Instead use own.getVehicleDetails().add(vh). This will add the new vehicleDetails entity to the existing vehicleDetails set associated with ownerDetails instead of replacing it.
So I have really been struggling to figure this out but there doesn't seem to be good documentation on how to do this. I have an entity RepairMan with a list of Skill entities. I need a query that can return a List<RepairMan> whose list of skills contain all the skill id's. Here is what the entities look like:
#Entity
#Table(name = "REPAIRMAN")
public class RepairMan implements Serializable
{
private static final long serialVersionUID = 8151638047721448259L;
#SequenceGenerator(name="REPAIRMAN_SEQ", sequenceName="REPAIRMAN_SEQ", allocationSize=1, initialValue=100)
#Id #GeneratedValue(generator="REPAIRMAN_SEQ")
private Long id;
#OneToMany
#JoinTable(name="REPAIRMAN_SKILLS", joinColumns=#JoinColumn(name="REPAIRMAN_ID"), inverseJoinColumns=#JoinColumn(name="SKILL_ID"))
private List<Skill> skills;
....
}
#Entity
#Table(name = "SKILL")
public abstract class Skill implements Serializable
{
private static final long serialVersionUID = -5272849377636005084L;
#SequenceGenerator(name="SKILL_SEQ_GEN", sequenceName="SKILL_SEQ", allocationSize=1, initialValue=100)
#Id
#GeneratedValue(generator="SKILL_SEQ_GEN", strategy=GenerationType.SEQUENCE)
private Long id;
#Column(name="NAME")
private String name;
#Column(name="DESCRIPTION")
private String description;
...
}
And here's the desired signature and what I have been able to work out in my mind:
public class RepairManRepositoryImpl extends QueryDslRepositorySupport implements RepairManRepositoryCustom
{
public CompanyInspectorRepositoryImpl()
{
super(RepairMan.class);
}
#Override
public List<RepairMan> getRepairMenByRequiredSkills(List<Long> skillIds)
{
PathBuilder<RepairMan> repairManPath = new PathBuilder<>(RepairMan.class, "repairman");
PathBuilder repairManSkillsPath = repairManPath.get("skills"); // probably wrong
BooleanBuilder hasAllSkills = new BooleanBuilder();
for (Long skillId : skillIds)
{
hasAllSkills.and(repairManSkillsPath.getNumber("id", Long.class).eq(skillId));
}
JPAQuery query = new JPAQuery(getEntityManager())
.from(repairManPath)
//need to join the repairManSkills somehow
.where(hasAllSkills);
return query.list(repairManPath);
}
}
I know this doesn't exactly work, plus I understand it would be easier to use the Qclasses but for compatibility reasons I can't do Qclasses.
I have a entity that has two Many-To-One relationships, and one of them cascades on save just fine and the other one returns:
Exception in thread "main" org.hibernate.TransientObjectException: object references an
unsaved transient instance - save the transient instance before flushing : dto.publicSchema.Pessoas
Here is the code of the entity that works:
#Entity
#Table(name="`Doc_tipo`", schema="public")
public class Doc_tipo implements Serializable {
private static final long serialVersionUID = 1859372890916956036L;
#Id
#Column(nullable=false)
private int tp_doc;
#Column(nullable=false,columnDefinition="CHAR(255)")
private String descricao;
#Column(nullable=false,columnDefinition="CHAR(255)")
private String tp_emissor;
//getters and setters
}
And here is the code of the entity that will not allow cascade:
#Entity
#Table(name="`Pessoas`", schema="public")
public class Pessoas implements Serializable {
private static final long serialVersionUID = 8292302132119274975L;
#Id #GeneratedValue
#Column(nullable=false,columnDefinition="serial NOT NULL")
private int seq_pessoa;
static Date padrao_dt_criacao = new Date();
#Column(nullable=false, columnDefinition="date NOT NULL")
private Date dt_criacao = padrao_dt_criacao;
#Column(columnDefinition="CHAR(255)")
private String nome;
#Column(columnDefinition="CHAR(1) NULL")
private char tp_pessoa;
#Column(columnDefinition="CHAR(255)")
private String fantasia;
#Column(columnDefinition="VARCHAR(25)")
private String idioma;
#Column(columnDefinition="VARCHAR(25)")
private String login;
#Column(columnDefinition="VARCHAR(25)")
private String senha;
static Date padrao_dt_i = new Date();
#Column(nullable=false, columnDefinition="date NOT NULL")
private Date dt_i = padrao_dt_i;
//Pessoa está ativa para o sitema se este campo estiver em branco
#Column(columnDefinition="date")
private Date dt_f;
#Column(columnDefinition="oid")
private int foto;
//getters and setters
}
And here is the class that has relationships Many-To-One with the two above
but cascade will only work on the first one:
#Entity
#Table(name="`Documentos`", schema="public")
public class Documentos implements Serializable {
private static final long serialVersionUID = -4874330647877687810L;
#Id
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="seq_pessoa",columnDefinition="integer",referencedColumnName="seq_pessoa",nullable=false)
private Pessoas seq_pessoa;
#Id #GeneratedValue
#Column(nullable=false,columnDefinition="serial NOT NULL")
private int cd_doc;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="tp_doc",referencedColumnName="tp_doc",nullable=false)
private Doc_tipo tp_doc;
#Column(nullable=false)
private int tp_emissor;
#Column(nullable=false,columnDefinition="CHAR(2) NOT NULL DEFAULT 'DF'::bpchar")
private String tp_emissor_uf="DF";
#Column(columnDefinition="CHAR(5)")
private String alfa_doc;
#Column(nullable=false,columnDefinition="CHAR(20)")
private String nr_doc;
//Data de validade do documento
#Column(columnDefinition="date")
private Date dt_f_valid;
#Transient
transient static Date padrao_dt_i = new Date();
#Column(columnDefinition="date DEFAULT now()")
private Date dt_i = padrao_dt_i;
#Column(columnDefinition="date")
private Date dt_f;
//getters and setters
}
When I go to save a Documentos object hibernate inserts the Doc_tipo in to its table
as its supposed to, and instead of inserting the Pessoa object as well throws me that exception.
Here is the class that manipulates the session(it's just for tests):
public class Hibernate {
public static SessionFactory getSessionFactory() {
SessionFactory sessionFactory = null;
try {
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (HibernateException hbe) {
hbe.printStackTrace();
}
return sessionFactory;
}
public static void main(String[] args) {
SessionFactory sessionFactory = getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Pessoas a = new Pessoas();
a.setDt_criacao(new Date());
a.setDt_f(new Date());
a.setDt_i(new Date());
a.setFantasia("teste");
a.setFoto(12);
a.setIdioma("aa");
a.setLogin("aa");
a.setNome("aa");
a.setSenha("a");
a.setTp_pessoa('H');
Doc_tipo b = new Doc_tipo();
b.setDescricao("aa");
b.setTp_doc(5);
b.setTp_emissor("aaa");
Documentos c = new Documentos();
c.setAlfa_doc("aaa");
c.setDt_f(new Date());
c.setDt_f_valid(new Date());
c.setDt_i(new Date());
c.setNr_doc("aa");
c.setSeq_pessoa(a);
c.setTp_doc(b);
c.setTp_emissor(1);
c.setTp_emissor_uf("aa");
//session.save(a);
session.save(c);
session.getTransaction().commit();
session.close();
}
}
If i remove the comment on the save() Pessoas object, everything works fine, but i shouldn't have to do that, the same exception happens when i try to cascade save in another
entity that has a Many-To-One relationship with Pessoas too.
Documentos references Pessoas with primary key (Pessoas.seq_pessoa) which is only created after it has been saved/flushed to database as Pessoas uses serial. So there is nothing to reference with before save/persist actually happens.
Also, you shouldn't use multiple #Id annotations to define composite identity unless you are also defining #IdClass that holds aforementioned #Id fields. Or you could you #EmbeddedId annotation as well. JPA supports two different approaches for compound PKs. In each case there must be a PK class that includes the fields.
A) Multiple #Id fields/attributes on the entity. Names and types of fields in the entity must match those in the PK class. Must also have an #IdClass annotation on the class. Ex:
public class EmpPK {
int id;
String name;
...
}
#Entity
#IdClass(EmpPK.class)
public class Employee {
#Id int id;
#Id String name;
...
}
B) Embed an attribute of the PK class in the entity. In this case the attribute is marked with #EmbeddedId and the PK class must be annotated with #Embeddable. Ex:
#Embeddable
public class EmpPK {
int id;
String name;
...
}
#Entity
public class Employee {
#EmbeddedId EmpPK empId;
...
}