Will my Spring Data Jpa method return all foreign fields? - spring-data-jpa

If I have a table like this :
Client
private Long int;
private String name;
#ManyToOne(mappedBy="otherField")
private Address addresses;
And I Create a repository that extends JPA Repository. Given the name of the client, I want to get as results also the Address Table fields.
Using the method
Client findByName(String name)
Will my this also return all the fields that are on the Address Table ?
Like:
Address
private Long id;
private String city;
private Int code;
private String street;

From the docs
The Hibernate recommendation is to statically mark all associations
lazy and to use dynamic fetching strategies for eagerness. This is
unfortunately at odds with the JPA specification which defines that
all one-to-one and many-to-one associations should be eagerly fetched
by default. Hibernate, as a JPA provider, honors that default.
So Hibernate behaves the same as JPA:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
Also take a look at the JPA sepcifications here.

Related

Best practice of handling relations between tables in Spring Data R2dbc

I tried to create a user/roles relation in RDBMS and want to use R2dbc(Spring Data R2dbc) to shake hands with the backend database.
Assume there are three tables, users, roles, and user_roles.
#Table("users")
class User {
#Id
private String username;
private String password;
private String email;
#Builder.Default
private boolean active = true;
#Builder.Default
private List<String> roles = new ArrayList<>();
#Column("created_at")
private LocalDateTime createdDate;
}
Unlike JPA, R2dbc reuses the spring-data-relational-common(which is also used in Spring Data Jdbc) to annotate the tables, but there is no facility to resolve the relations, such as the roles here.
Spring Data R2DBC currently does not support relationships.
So what you would do is to have a separate entity User2Role with two properties: String username and String rolename referencing the ids of the referenced entities.
Since you also tagged the question Spring Data JDBC: Spring Data JDBC does support 1:1 and 1:M references, but not M:1 or M:N relationships. See https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates for some background on that.
Spring Data R2DBC might eventually move to the same model.

JPA entity proxy issue comparing with null value

Some JPA provider like Hibernate uses Proxy to handle lazy initialization. Consider the following example:
#Entity
public class Person {
#Id
private Long id;
#ManyToOne(fetch=FetchType.LAZY)
private House house;
}
#Entity
public class House {
#Id
private Long id;
#Embedded
private Address address;
}
When fetching a Person entity, its house property is set to a Proxy (lazy).
Person person = em.find(Person.class, 1);
House house = person.getHouse(); // Proxy
if (house == null)
System.out.println("has no house);
else
System.out.println("has a house");
If the person does not have a house, the person object has a Proxy of house (not null). The code above will print wrong message. Is this an issue for JPA proxy?
As a matter of fact, I'm surprised you're facing this issue. According to this question: Making a OneToOne-relation lazy, lazy optional many-to-one associations should work just fine; it is the one-to-one associations that cause problems. The issue here is that without enhancement, Hibernate cannot automagically turn the proxy into a null reference. Are you actually seeing this behavior in Hibernate?
In any case, you should be able to resolve the issue by enabling enhancement. This way, Hibernate is able to overwrite the getter method to return null if the initialized proxy does not represent a valid House. Not sure how the issue is resolved by other providers, though.

How to retrieve nested data in JPQL?

working with OpenJPA2 persistence. I have a very simple entity class, that does have a String property and a List property. I do persist its instances flawlessly with the nested List (in a JSF2 web project). I check the database and there appears two tables (I use automatic schema generation), one for the entity itself, and other table for the nested List. All data persisted using EntityManager is stored fine on both tables.
Problem is I cannot retrieve nested data. I mean, I do a Query for getting all instances of the entity, but the List of all instances come empty.
(DB Engine is MySQL. ORM is OpenJPA2. Server is TomEE 1.6. IDE is Netbeans 8. I use automatic schema generation, so I DO NOT WANT to design the database tables, and I DO WANT to let the ORM create the tables, so I can work purely with objects and forget about DB.)
following is Entity Class code:
#Entity
public class Cliente implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String nombre;
#ElementCollection
private List<String> emails = new ArrayList<String>();
// getters and setters omitted for brevity.
It does have an associated Facade Class, which is ClienteFacade. It includes the getAll method which uses a JPQL Query.
public List<Cliente> listaClientes(){
Query query = em.createQuery("SELECT c FROM Cliente c");
return query.getResultList(); }
Problem is, I get all instances of the entity in a List, but all lists of List emails come out empty. I think problem may be in the JPQL query. Still trying to learn JPQL with some difficulty... so please, How can I retrieve the nested data with JPQL?
Many thanks!
Try #ElementCollection(fetch = FetchType.EAGER) because the default type is lazy. That means that the lists are not loaded directly.

Does Hibernate Search load entity associations and can I mix free text queries with native SQL?

package example;
...
#Entity
#Indexed
public class Book {
#Id
#GeneratedValue
private Integer id;
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String title;
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String subtitle;
#Field(index = Index.YES, analyze=Analyze.NO, store = Store.YES)
#DateBridge(resolution = Resolution.DAY)
private Date publicationDate;
#IndexedEmbedded
#ManyToMany
private Set<Author> authors = new HashSet<Author>();
#OneToMany(mappedBy="book")
List<BookPages> bookPages;
}
1) If the search result is of type Book.class does the result contain #ManyToOne objects (bookPages) or do I have to load them separately? Because I need them for showing the result.
2) Is it possible to add a native sql clause to the search? Because I need to limit the result and for that I have to JOIN another table which is not declared in Book.class.
That is a basic Hibernate ORM question, not related to Hibernate Search. Yes you can always navigate from one entity to its relations by just invoking the getter / accessing the fields: depending on your (configurable) fetch strategy it will either have the relation preloaded in "one shot" when loading the main entity (likely with a JOIN) or fetch it transparently on demand. This configuration is however not have any effect on functionality, more a performance tuning option.
No you can't mix SQL with an Hibernate Search (Fulltext) query; what you can do is to expose the needed data from the other table in the mapping - which would be a cleaner mapping anyway - and then use the Hibernate Search annotations to make sure all fields you need are indexed as well, so that you can include the restrictions in the FullTextQuery directly; fill perform much faster as well than any SQL.
It is not possible to mix native SQL with hibernate search query, as there is no way to intersect the results from both queries without iterating on at least one of the results.
See the documentation reference about this exact question.
Hibernate Search - FAQ - Can I mix HQL and Lucene queries?
http://hibernate.org/search/faq/

Mapping xml to jpa entities using JAXB

Isn't it possible to map xml to jpa entities using JAXB? Will Eclipselink Moxy be helpful?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
Yes you can map JPA entities to XML, and the following are some ways that EclipseLink JAXB (MOXy) makes this easier.
1. Bidirectional Mappings
Customer
import javax.persistence.*;
#Entity
public class Customer {
#Id
private long id;
#OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
private Address address;
}
Address
import javax.persistence.*;
import org.eclipse.persistence.oxm.annotations.*;
#Entity
public class Address implements Serializable {
#Id
private long id;
#OneToOne
#JoinColumn(name="ID")
#MapsId
#XmlInverseReference(mappedBy="address")
private Customer customer;
}
For More Information
http://blog.bdoughan.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-25.html
2. Mapping Compound Key Relationships
We normally think of mapping a tree of objects to XML, however JAXB supports using the combination of #XmlID/#XmlIDREF to map relationship between nodes representing a graph. The standard mechanism is one key, to one foreign key. JPA supports the concept of composite keys and so does MOXy using #XmlKey and #XmlJoinNodes (similar to #XmlJoinColumns in JPA).
Employee
#Entity
#IdClass(EmployeeId.class)
public class Employee {
#Id
#Column(name="E_ID")
#XmlID
private BigDecimal eId;
#Id
#XmlKey
private String country;
#OneToMany(mappedBy="contact")
#XmlInverseReference(mappedBy="contact")
private List<PhoneNumber> contactNumber;
}
PhoneNumber
#Entity
public class PhoneNumber {
#ManyToOne
#JoinColumns({
#JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
#JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
#XmlJoinNodes( {
#XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"),
#XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()")
})
private Employee contact;
}
For More Information
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA/CompoundPrimaryKeys
3. MOXy allows for Composite and Embedded Keys
JPA can also use embedded key classes to represent composite keys. MOXy also supports this style of composite keys.
For More Information
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA/EmbeddedIdClass
4. EclipseLink JAXB (MOXy) and EclipseLink JPA Have Shared Concepts
EclipseLink provides both JAXB and JPA implementations that share a common core. This means that they share many of the same concepts, such as:
Virtual Access Methods
EclipseLink supports the concept of virtual properties. This is useful when creating a multi-tenant application where you want per-tenant customizations. This concept is upported in both EclipseLink's JPA and JAXB implementations.
http://blog.bdoughan.com/2011/06/moxy-extensible-models-multi-tenant.html
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Extensibility