#Transient in spring data doesn't work - java

I have Settlement entity
#Entity
#Table(name = "settlement")
public class Settlement {
#ManyToOne
#JoinColumn(name = "subscription_x_product_id")
private ProductSubscription productSubscription;
which related to ProductSubscription entity
#Entity
#Table(name = "subscriptionproduct")
public class ProductSubscription {
#ManyToOne
#JoinColumn(name = "product_id")
private Product product;
which related to Product entity
#Entity
public class Product {
#Transient
private String enabled;
in Product entity i have field enabled which annotated with #org.springframework.data.annotation.Transient.
also I have Repository
public interface SettlementRepository extends JpaRepository<Settlement, Integer>
when I call SettlementRepository.findAll(); it give exception Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'enabled'.
How can I ignore the enabled field from being loaded from the DB ?

I found the solution, the problem was in Annotation #org.springframework.data.annotation.Transient once I changed to #javax.persistence.Transient it worked fine.

Related

Spring Data JPA persisting one to many referenced entity

I am using Spring Data JPA (1.4.0, spring boot) and have following code
ExternalOrder entity:
#Entity
#Table(name = "External_Orders")
public class ExternalOrder {
...
#OneToMany(fetch = FetchType.LAZY, mappedBy = "externalOrder", orphanRemoval = true, cascade = CascadeType.ALL)
private List<ExternalOrderElement> elements;
...
}
ExternalOrderElement entity:
#Entity
#Table(name = "External_Order_Elements")
public class ExternalOrderElement implements Serializable {
#Id
#ManyToOne(optional = false)
#JoinColumn(name = "ExternalOrderID")
private ExternalOrder externalOrder;
#Id
#OneToOne(optional = false)
#JoinColumn(name = "BoardGameID")
private BoardGame boardGame;
...
}
I also have default Crud repository for ExternalOrder
public interface ExternalOrderRepository extends CrudRepository<ExternalOrder, Integer>{
}
And I want to add some element to external order and persist it. I've managed to do this creating my custom repostitory interface and implementing it, but I've now tried to move the logic to the service method like so:
#Override
#Transactional
public void addElementToExternalOrder(int externalOrderId, ExternalOrderElement element) {
ExternalOrder externalOrder = findExternalOrderById(externalOrderId);
element.setExternalOrder(externalOrder);
externalOrder.getElements().add(element);
externalOrderRepository.save(externalOrder);
}
And that results in following Exception upon execution
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'ExternalOrderID' cannot be null
Is there something I am missing about the JPA? It seems like I haven't set the ExternalOrder reference on ExternalOrderElement, but I've done it.
Thank you guys for help in advance.

Hibernate/JPA querying embeddable property of a joined subclass

I have the following entities: ShoppingCart, abstract class User and EndUser that extends User. AddressDetails is an embedable that is embeded into EndUser entity.
My query looks like this: SELECT sc FROM ShoppingCart sc JOIN sc.endUser as endUser WHERE endUser.name EQ someName and endUser.addressDetails.zip EQ 1234
When I remove the second part of the WHERE clause, and leave just the endUser.name part, everything works fine (name is a property of endUser entity class which is a subclass of User entity class).
However, when I try the whole query I get:
org.hibernate.QueryException: could not resolve property: zip of:
ShoppingCart:
#Entity
public class ShoppingCart {
...
#ManyToOne(fetch = FetchType.LAZY)
#JoinTable
private EndUser endUser;
}
User:
#Entity
public abstract class User {
...
}
EndUser:
#Entity
public class EndUser extends User {
...
#Column
private String name;
#Embeded
private AddressDetails addressDetails;
...
}
Address Details:
#Embeddable
public class AddressDetails {
...
private int zip;
...
}
I actually found the problem.
When I change FetchType to EAGER on #ManyToOne reladtionship between ShoppingCart and endUser the query works.
So it should be:
#ManyToOne(fetch = FetchType.EAGER)
#JoinTable
private EndUser endUser;

Receiving a org.hibernate.MappingException: Duplicate property mapping

I'm attempting to build an application level view with Spring JPA. I'm also using lombok.
There is an existing client already using this web service which can't be changed at this time.
We have a new client which needs the same data and even more now. So I thought this could
be addressed with an application level view so to speak.
The basic scope of the problem is I have 3 entities: A, B and C.
A and C are entities pointed at the same table. C has more properties than A.
Both C and A have references to B.
#Entity
#Getter
#Setter
#Table(name="Foo", schema="dbz")
public class A {
#Id
#Column(name="FOO_I")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#OneToMany(fetch =FetchType.EAGER, cascade= CascadeType.ALL)
#JoinColumn(name="FOO_I",nullable=false)
private Set<B> items = new HashSet<B>();
#Column(name="X")
private String x;
}
#Entity
#Getter
#Setter
#Table(name="Bar", schema="dbz")
public class B {
#Id
#Column(name="BAR_I")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name="Y")
private String y;
#Column(name="Z")
private int z;
}
#Entity
#Getter
#Setter
#Table(name="Foo", schema="dbz")
public class C {
#Id
#Column(name="FOO_I")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#OneToMany(fetch =FetchType.EAGER, cascade= CascadeType.ALL)
#JoinColumn(name="FOO_I",nullable=false)
private Set<B> items = new HashSet<B>();
#Column(name="X")
private String x;
#Column(name="MoreData")
private String moreData;
//And much more other data...
}
When I comment out the #Entity and #Table on class C and rebuild, I don't get an exception in my validation tests.
When I leave the #Entity and #Table annotations on class C, I get the following exception:
Caused by: org.hibernate.MappingException: Duplicate property mapping of _items_FOO_IBackref found in com.acme.Bar
If I rename items to bars in C, then I get the following exception:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.acme.Bar column: FOO_I (should be mapped with insert="false" update="false")
Is there any way to get hibernate to accept 2 java classes backed by the same table which relate to another entity? I'm not sure if I am missing something here or if this is a framework limitation.
You are using component mapping so use #Embedded annotation for the A class without using #Entity, #Id and #Table annotations here is a useful link;
http://www.dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-component-using-annotations-1.html

How do I avoid NullPointerException with OneToOne mapping against a parent entity class?

I have searched and found similar issues, but they don't quite seem to be the same problem as
Why am I getting this NullPointer exception?
OneToOne Mapping with hibernate/JBoss/Seam
ANN-613 - NPE when mappedBy property is wrong on a #OneToOne
ANN-558 - #OneToMany(mappedBy="") can not recognize properties in parent classes
Hibernate Users - NPE with #Id on #OneToOne
I have a few entities mapped like this:
Person
|
+--User
I want to add a new entity PersonPartDeux with a OneToOne mapping to Person. The resulting mapping should look something like this:
Person + PersonPartDeux
|
+--User
When I do so, a NullPointerException is thrown while trying to load the mapping:
java.lang.NullPointerException
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:135)
How do I specify the mapping so I can avoid this exception?
Here's my code:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Person implements Serializable
{
#Id
#GeneratedValue
public Long id;
#Version
public int version = 0;
public String name;
#OneToOne(cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
public PersonPartDeux personPartDeux;
}
#Entity
public class PersonPartDeux implements Serializable
{
#Id
#GeneratedValue(generator = "person-primarykey")
#GenericGenerator(
name = "person-primarykey",
strategy = "foreign",
parameters = #Parameter(name = "property", value = "person")
)
public Long id = null;
#Version
public int version = 0;
#OneToOne(optional=false, mappedBy="person")
public Person person;
public String someText;
}
#Entity
#PrimaryKeyJoinColumn(name = "person_Id")
public class User extends Person
{
public String username;
public String password;
}
As for why I'm bothering, I need both the inheritance and the OneToOne mapping to solve different known issues in my application.
Attach the Hibernate source to your project, so you can click thru or 'Open Type' (Ctrl-Shift-T in Eclipse) to view the OneToOneSecondPass source.
Seeing the source, will give you a clear indication as to what needs to be specified.
In my source (Hibernate 4.1.7), line 135 is
propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
However you're probably using an earlier version.
Looking at the mappings, I'm suspicious of the #OneToOne definition -- mappedBy="person".
#OneToOne(optional=false, mappedBy="person")
public Person person;
What does it usefully mean, to map an association property by itself? Hibernate already knows the property is a OneToOne -- you just told it that.
Pointing the underpinning mapping/ FK of the property, at itself.. probably isn't actually telling Hibernate any correct or useful information.
Here's an example from the HB dosc, perhaps showing better how to do what you want:
#Entity
class MedicalHistory implements Serializable {
#Id Integer id;
#MapsId #OneToOne
#JoinColumn(name = "patient_id")
Person patient;
}
#Entity
class Person {
#Id #GeneratedValue Integer id;
}
Source: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/
(3.5 docs off JBoss site.)
Cheers, hope this helps.

Hibernate inheritance, Collections and #OrderedBy superclass attribute generates MySQL syntax Error

I' using Hibernate 3.6.1 to map three entities
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Entry {
private Long id;
private Date publishedAt;
#Id
public getId() {...}
...
}
#Entity
public class Category {
private Long id;
List<Podcast> podcasts;
#Id
public getId() {...}
#OneToMany(mappedBy = "category", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
#OrderBy("publishedAt")
public List<Podcast> getPodcasts() {
return podcasts;
}
}
and
#Entity
public class Podcast extends Entry {
private Category category;
#ManyToOne(fetch = FetchType.EAGER)
public PodcastsCategory getCategory() {
return category;
}
}
If i try to fetch a Category instance, i get an Exception
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'podcasts0_.Entry.publishedAt' in 'order clause'
What causes this exception? Whats wrong with this mapping?
It's caused by the following bug: HHH-3577 Wrong SQL in order by clause when using joined subclasses.
As a workaround you can remove #OrderBy and fetch = FetchType.EAGER on podcasts and load category using the following query instead of get():
SELECT DISTINCT c
FROM Category c LEFT JOIN FETCH c.podcasts p
WHERE c.id = ?
ORDER BY p.publishedAt
You could try the annotation #MappedSuperClass. See section 2.2.4.4. Inherit properties from superclasses of the hibernate documentation.

Categories