Get attributes in view from inherited objet - jpa

In one of my jsf view I'm displaying a list of users with some information like : CardId (child), Firstname (parent), Lastname (parent).
Only the attributes from the child class are displayed.
The class User contain the Firsname and Lastname and the child a new attribute cardId.
<h:selectOneMenu>
<f:selectItem itemLabel="Looking into my pocket ..." />
<f:selectItems value="#{PresentationBean.getReaders()}" var="reader" itemLabel="#{reader.cardId} (#{reader.firstname}-#{reader.lastname})" itemValue="#{reader.cardId}" />
</h:selectOneMenu>
Child class
#Entity
public class Reader extends User {
private int cardId;
//some code
}
Parent class
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#Entity
public abstract class User {
private String firstname, lastname;
//some code
}
As result my dropdown only display the CardId
The log also state that all the field are queried.
20:36:26,627 INFO [stdout] (default task-26) Hibernate: select reader0_.email as email2_4_, reader0_.city as city3_4_, reader0_.street as street4_4_, reader0_.zipCode as zipCode5_4_, reader0_.firstname as firstnam6_4_, reader0_.lastname as lastname7_4_, reader0_.accountBalance as accountB8_4_, reader0_.cardId as cardId9_4_ from User reader0_ where reader0_.DTYPE='Reader'

Related

jpa #Inheritance(strategy=InheritanceType.JOINED) how to select super entity not contain child

I have question: Let's assume I have two classes User and person, person extends User. In User I have #Inheritance(strategy=InheritanceType.JOINED). Sometimes I only want to select the user info not contain the child table info,
User.java(super class)
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name = "user_type")
#Table(name = "users")
public class User {.........}
Person.java
#Entity
public class Person extends User {......}
Company.java
#Entity
public class Company extends User {.............}
UserRepository.java
#Transactional
public interface UserRepository extends UserBaseRepository<User> {
//#Query(value="select u from User u where u.email=?1")
#Query(value="select u.id,u.email from User u where u.email=?1")
User getUser(String email);
#Query("select u from User u where u.email=?1")
User getUser2(String email);
#Query(value="select * from Users where email=:email",nativeQuery=true)
User getUser3(String email);
}
The following exception occurs:
Hibernate: select user0_.id as col_0_0_, user0_.email as col_1_0_ from users user0_ where user0_.email=?
org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.Object[] to type netgloo.models.User for value '{1, 635#qq.com}';
nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.lang.Long to type netgloo.models.User
how to get the user info not contain Person,Company
how to get the Person info not contain user ,Company
To select only the user you can use the JPQL TYPE() operator like this:
SELECT u FROM User u WHERE TYPE(u) := User
Here is complete explaination: https://stackoverflow.com/a/3766541/534877

Query to find Parent entity by Child attribute where Parent also have same attritube, in spring data jpa

I am trying to create a query in Spring-data-jpa to find a Person entity by Address's id. Person have OneToOne relationship with Address and both have id as primary key.
public abstract class AbstractEntity{
#Id
Long id;
}
public class Person extends AbstractEntity {
#OneToOne
Address address;
}
public class Address extends AbstractEntity {
}
public interface PersonRepository implements JpaRepository<Person, Long> {
Person findByAddressId(Long addressId); // Throws cannot create metamodel exception
Person findByAddress_Id(Long addressId); // Throws cannot create metamodel exception
}
I'm thinking that the method name findByAddressId and findByAddress_Id are ambiguous for Spring data jpa query look-up strategies as both Person and Address entities have id as their attributes.
Is it possible to write query in Spring-data-jpa to find parent entity by child attribute where parent and child both have same attribute, without writing SQL?

JPA EAGER fetch works only if server is restarted

Good evening everybody, this is my first post on Stack Overflow.
I have been quite recently introduced to Java 6 EE and, in particular, to JPA as part of the JSF 2.1 framework and I am now facing a strange behavior that I would like you to help me understand.
In our project (developed using NetBeans 7.2) we have several one-to-many relationship and we would like to navigate them the same way we navigate many-to-one ones. The fact is that, instead, we are able to make them work as we want only after having restarted the application server (Glassfish 3.1.2) and, in addition, this behavior lasts only till the next deployment; which means we need to restart Glassfish every time we apply a modification...
Here are some code excerpts to help you understand our situation.
This represents our main entity (Person) that has, among the others, a one-to-many relationship with Email as well as with Phone and a many-to-one relationship with AccountType
#Entity
public class Person implements Serializable {
//
//private non-collection fields including id
//
#OneToMany(mappedBy="person", fetch=FetchType.EAGER)
private Collection<Email> personEmails;
#OneToMany(mappedBy="person")
private Collection<Phone> personPhones;
#ManyToOne
private AccountType accountType;
//
// getter and setter, hashCode, isEqual and toString
//
}
And these are Email...
#Entity
public class Email implements Serializable {
//
//private non-collection fields including id
//
private String address;
#ManyToOne
private Person person;
//
// getter and setter, hashCode, isEqual and toString
//
}
... Phone ...
#Entity
public class Phone implements Serializable {
//
//private non-collection fields including id
//
private String number;
#ManyToOne
private Person person;
//
// getter and setter, hashCode, isEqual and toString
//
}
... and AccountType
#Entity
public class AccounType implements Serializable {
//
//private non-collection fields including id
//
private String name;
#OneToMany(mappedBy="accountType")
private Collection<Person> persons;
//
// getter and setter, hashCode, isEqual and toString
//
}
We have then set up a sample page to test how that three fields in Person are actually fetched.
This represents the xhtml page...
<h:form id="form">
<h:panelGrid columns="2">
<h:outputLabel value="forename" />
<h:outputLabel value="#{meBean.currentUser.forename}" />
<h:outputLabel value="emails" />
<h:outputLabel value="#{meBean.currentUser.personEmails.size()}" />
<h:outputLabel value="phones" />
<h:outputLabel value="#{meBean.currentUser.personPhones}" />
<h:outputLabel value="accountType" />
<h:outputLabel value="#{meBean.currentUser.accountType.name}" />
</h:panelGrid>
</h:form>
... and this the controller
#ManagedBean
#RequestScoped
public class MeBean {
#EJB
private PersonFacade personFacade;
private Person currentUser;
public MeBean() {
init();
}
#PostConstruct
private void init() {
// Hard-coding user details
try {
this.currentUser = this.personFacade.getFromUsername("user1");
this.currentUser.getPersonPhones().isEmpty();
} catch (Exception e) {
}
}
public Person getCurrentUser() {
return currentUser;
}
public void setCurrentUser(Person currentUser) {
this.currentUser = currentUser;
}
}
Now, the result we get is the one we expect only if we access the page right after having restarted the application server.
forename Alice
emails 2
phones {[sums.groupa.entities.Phone[id=38]]}
accountType Student
If we modify anything (except for the view) and save, after the inevitable deploy, the result is different.
forename Alice
emails 0
phones {[]}
accountType Student
Why is that happening and how can we avoid it?
Thanks in advance.
AG
A couple of contributors (that I want to thank for their quick replies) asked for the PersonFacade implementation.
public Person getFromUsername(String username)
{
try
{
Query q = em.createQuery("SELECT p FROM Person p LEFT JOIN FETCH p.personEmails WHERE UPPER(p.username) = :username");
q.setParameter("username", username.toUpperCase());
return (Person) q.getSingleResult();
}
catch (Exception ex)
{
Logger.getLogger(PersonFacade.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
As you can see I tried to use FETCH JOIN as suggested but the query is getting out too many results: it should fetch only one instance of Person representing Alice and containing two instances of Email in the personEmails field but I suspect it is getting two different instances of Person, each having a different instance of Email attached.
The original query was as follows:
SELECT p FROM Person p WHERE UPPER(p.username) = :username
Thanks again.
AG
I don't know how you wrote your personFacade and got the Person entity.
But I guess you used query.
If you are using JPQL, try fetch join.

With Entity Framework code-first, how to Insert object with existing property

Here is the simple case.
I have a Customer record defined like this:
public class Customer
{
[Key]
public string Id { get;}
public UsState UsState { get; set; }
}
public class UsState
{
[Key]
public string StateAbbreviation {get;set;}
public string StateName {get;set;}
}
I already have my UsState's populated with the 50 states, now I want to insert one Customer record that ties to an existing state.
If I say something like:
Customer customer = new Customer()
{
UsState = "CA",
Id = 1001
}
dbContext.Customers.add(customer);
I get an error saying state is trying to be inserted again.
How can I get the add to use an existing state and not try and re-insert it. My real problem has lots of nested objects that may exist so I need to solve this in general.
Thanks
Two ways I know is:
Set EntityState to what is appropriate for your action or
Get the UsState from the database and add it to the customer right before saving, which will give it an EntityState of UnModified or something like that.
to change the EntityState you need to get to the ObjectContext of your DbContext like shown in this thread: Entity Framework Code First - No Detach() method on DbContext
If you think about this in terms of table data, your Customer table should have a column in it that describes the customer's state. You also have a state table that you can use to join together to get the state name.
CREATE TABLE customer (
id VARCHAR(10),
state CHAR(2)
)
CREATE TABLE state (
stateabbreviation CHAR(2),
statename VARCHAR(50)
)
The "state" column is a just a string representing the state. So your class should be defined the same way, with and ID and a State, and if you want to include the information for your USState class, defined a property of type UsState with a ForeignKey defined:
public class Customer
{
[Key]
public string Id { get;}
public string State { get; set; }
[ForeignKey("State")]
public UsState UsState { get; set; }
}
Then, when you create a new record, set the text of the string, not the UsState object.
Customer customer = new Customer()
{
State = "CA",
Id = 1001
}
dbContext.Customers.add(customer);

How do I represent this using JPA?

I would like a 'RolesPlayed' entity with the following columns
user
role
department/project/group
All the three columns above constitute a composite primary key. I would like to know if defining a column to be one of department/project/group possible ? If yes, how ? Or do I need to break the entity into DepartmentRoles, GroupRoles and ProjectRoles.
Thanks.
You could use polymorphism with an abstract base class to do that.
#Entity
public class RolePlayed {
#ManyToOne
private User user;
#ManyToOne
private Role role;
#ManyToOne
private Body body;
...
}
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Body {
...
}
#Entity
public class Department extends Body {
...
}
#Entity
public class Project extends Body {
...
}
#Entity
public class Group extends Body {
...
}
Check out the Polymorphism section in the Java Enterprise tutorial for a good overview.
Alternatively, you could also make the RolePlayed entity abstract, with DepartmentRole, GroupRole and ProjectRole implementations.