Hibernate is persisting zero instead of double values - java

I am using Spring Boot 1.3.7.RELEASE as application framework, Hibernate as JPA implementation, Spring Data as data access interface, and MySQL 5.7.15 as storage server. I have two models: Agency and ServiceAreaCoverage. Agency has oneToOne unidirectional with ServiceAreaCoverage at the moment. Here's my application model's and mapping's.
#Entity
#Table(name = "agencies")
public class Agency {
#Id
private String id;
private String name;
private long phoneNumber;
private String email;
private String websiteUrl;
private boolean active;
#OneToOne(cascade = CascadeType.PERSIST)
#JoinColumn(name = "service_area_coverage_id")
private ServiceAreaCoverage serviceAreaCoverage;
}
#Entity
#Table(name = "service_area_coverages")
public class ServiceAreaCoverage {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private double latitude;
private double longitude;
private double latitudeSpan;
private double longitudeSpan;
}
I am trying to save Agency with ServiceAreaCoverage using Spring Data JpaRepository's save method. Agency and ServiceAreaCoverage both get saved and key constraints are also properly managed. However, double values are not getting saved. Instead of double values, zero is getting saved. I cannot think of any reason for this result to happen nor I can think of troubleshooting idea's. So any help would really be appreciated guys. Here's my some other codes and references relative to this matter.
Service Code:
#Service
public class AgencyServiceImpl implements AgencyService {
#Autowired
private AgencyRepository agencyRepository;
#Override
public void createAgency(Agency agency) {
this.agencyRepository.save(agency);
}
}
Repository Interface Code:
#Repository
public interface AgencyRepository extends JpaRepository<Agency, String> {
}
Generated Table Details:
Agencies Table:
ServiceAreaCoverage Table:

I think this may help you.
You should use wrapper classes instead of primitives.
Please change double to Double in your ServiceAreaCoverage class as it can hold even null value. Make sure the getter/setters are in Double instead of double.
#Entity
#Table(name = "service_area_coverages")
public class ServiceAreaCoverage {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Double latitude;
private Double longitude;
private Double latitudeSpan;
private Double longitudeSpan;
}
Note: You can not use the primitive double when the DB column is set as not-null="true".
Always use wrapper classes, so you don't have to think for 0 or null.

Related

Create a new JPA Entity to produce a new object from two tables

Hello programming council, this is my first use of JPA in anger.
I have 2 Tables:
Entity
#Table(name="category")
public class Category {
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name="category")
private String category;
#Column(name="budget")
private double budget;
#Column(name="savings")
private String savings;
#Column(name="archive")
private String archive;
Entity
#Table(name="Transaction")
public class Transaction {
#Id
#Column(name="transaction_no")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long transactionNo;
#Column(name="transaction_date")
private String transactionDate;
#Column(name="transaction_category")
private String transactionCategory;
#Column(name="transaction_description")
private String transactionDescription;
#Column(name="transaction_amount")
private double transcationAmount;
#Column(name="transaction_auto")
private String transactionAuto;
I want to create a new object called Tile which will contain String category and String balance, the SQL for which would be:
select t.transaction_category as category, sum(t.transaction_amount) as balance
from budgeteer.category c
join budgeteer.transaction t
on c.category = t.transaction_category
group by t.transaction_category;
What is the easiest/best way for me to accomplish this?
Thanks in advance.
Ok, so after a little more research, I discovered that I could actually just do this with the same Entity, repository and service without generating a table. You just need to leave out the #Table annotation when you create your entity.

Modelling optional one to many relationship - should I use inheritance?

I am trying to model a weather service that supports multiple locations. My application has 3 entities:
Location - information about the Location
Weather (includes location id) - A single hour of weather data
LocationWeather - Subclass of Location containing a List of Weather
I want Location to sometimes exist as a distinct entity from Weather. That way I can expose CRUD operations on the Location object without carrying the bloat of all of its weather data. However, I still want to satisfy the primary use case of returning weather for a given location, that's why LocationWeather exists.
Can what I want to do be done with inheritance? I've tried
#Entity
#Table(name="location")
#Inheritance(strategy = InheritanceType.JOINED)
public class Location {
but my subclass (LocationWeather) doesn't directly associate with a table. Should I move my List of Weather up to the Location object and somehow mark it as optional?
Location.java
#Entity
#Table(name="location")
public class Location {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="location_id")
private int id;
#Column(name="name")
private String name;
Weather.java
#Entity
#IdClass(WeatherId.class)
#Table(name="weather")
public class Weather {
#Id
#Column(name="location_id")
private int locationId;
#Id
#Column(name="time")
private Date time;
#Column(name="temperature")
private Double temperature;
LocationWeather.java
#Entity
public class LocationWeather extends Location{
#ElementCollection
#CollectionTable(name="weather", joinColumns= {#JoinColumn(name="location_id")})
#Column(name="weather")
private List<Weather> weather;
Figured it out. I was googling the wrong things. I should have been searching for "2 entities 1 table"
I was able to solve the issue by creating a #MappedSuperclass and creating Location and LocationWeather as a subclass of it.
Now I have:
MappedLocation.java
#MappedSuperclass
public class MappedLocation {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="location_id")
private int id;
#Column(name="name")
private String name;
Location.java
#Entity
#Table(name="location")
public class Location extends MappedLocation {
}
LocationWeather.java
#Entity
public class LocationWeather extends MappedLocation{
#ElementCollection
#CollectionTable(name="weather", joinColumns= {#JoinColumn(name="location_id")})
#Column(name="weather")
private List<Weather> weather;
More info: https://thoughts-on-java.org/hibernate-tips-map-multiple-entities-same-table/

When using createItem method with Location,Location Creates even if it got the same values in all columns

I use h2 in memory db and I don't want to create duplicate locations in my DataBase. Only when I use createItem and input location column id manualy it write it to the same location. Otherwise even if the country city gps coordinates are the same app write it to other location with it's id.
I tried to understand but It's not working
I got these entities.
#Entity
#Table(name = "item_System_items")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String title;
private String description;
private BigDecimal price;
private Integer stock;
#ManyToOne
#JoinColumn(name = "location_id")
#Cascade(value={org.hibernate.annotations.CascadeType.ALL})
private Location location;
And
#Entity
#Table(name = "item_System_locations")
public class Location {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String country;
private String city;
private String street;
private String gpsCoordinates;
SETTERS AND GETTERS IS THERE I JUST NOT POST THEM HERE
Controller
#RestController
#RequestMapping("/items")
public class ItemsController {
#Autowired
private ItemsService service;
#PostMapping
#ResponseStatus(value=HttpStatus.CREATED)
public int createItem(#RequestBody Item item) {
return service.createItem(item);
}
Service
#Service
#Transactional
public class ItemsService {
#Autowired
private ItemJPARepository repository;
public int createItem(Item item) {
return repository.save(item).getId();
}
I expect after re-coding app doesn't make new location if the column values are the same.
Thank you people!
If you really help me I would be so happy!
There is nothing in your Entity definitions to tell the ORM about the constraint you want.
You can add #UniqueConstraint to the #Table in your Location entity and specify which column(s) must all be in a unique combination (example given in the linked documentation):
#Table(
name="EMPLOYEE",
uniqueConstraints=
#UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
)
This will add a check in the database, if the ORM is managing your database schema, which will throw an exception when violated.

Aggregation relationship via JPA annotations

I am trying to establish the aggregation relationship between two Java classes through JPA annotations in order to persist them into a database.
public class Ticket
{
private String ticketNo;
private Date releasedDate;
private boolean printed;
}
public class Discount
{
private String percentage;
private Date releasedDate;
private boolean printed;
}
Such as mentioned here, the aggregation relationship is unidirectional and thus, only it is necessary to map one side. From the solution given by this page, I think the solution will be:
public class Discount
{
private String percentage;
private Date releasedDate;
private boolean printed;
#ManyToOne(name="TICKET_ID")
private Ticket ticket;
}
However, in some examples of aggregation, the many side class appears inside the one side class. Thus, I am considering this too:
public class Ticket
{
private String ticketNo;
private Date releasedDate;
private boolean printed;
#OneToMany(mappedBy="ticket")
private List<Discount> discounts = new ArrayList<Discount>();
}
Which option is the proper one?
This how you map a unidirectional many-to-one relationship:
#Entity
public class Ticket {
#Id
#GeneratedValue
private Long id;
private String ticketNo;
private Date releasedDate;
private boolean printed;
// getters and setters
}
#Entity
public class Discount {
#Id
#GeneratedValue
private Long id;
private String percentage;
private Date releasedDate;
private boolean printed;
#ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "TICKET_ID") // you can rename the join column
private Ticket ticket;
// getters and setters
}
Note:
JoinColumn (foreign key in the database terminology) must be on the many side of the relationship (this is the Discount in your case).
The #Id annotations are also mandatory. In this case, the ID will be generated by the persistence provider automatically. If you are using database sequence or table or some other strategy you can redefine it.
That looks right to me. A discount has a ticket. You could also include the discounts accessible from the tickets like ticket.getDiscounts() if you need to access them in a query such as SELECT t FROM Ticket t WHERE t.discounts.percentage >= :discountPercentage.
#Entity
public class Ticket {
#Id
private String ticketNo;
private Date releasedDate;
private boolean printed;
#OneToMany(mappedBy = "ticket", fetch = FetchType.LAZY)
private List<Discounts> discounts;
}
#Entity
public class Discount {
private String percentage;
private Date releasedDate;
private boolean printed;
#ManytoOne(name="TICKET_ID")
private Ticket ticket;
}
However, I wouldn't recommend using #OneToMany as this can create problems serializing too much data to JSON if you are returning this as JSON results or just lazily loading too much data by accident. You should always be able to work with just #ManyToOne as an example if you did not put the #OneToMany association query can be SELECT t FROM Discount d INNER JOIN d.ticket t WHERE d.percentage >= :discountPercentage

Joining two table in spring data JPA and Querying two table data from repository

I am using Sprind JPA, Spring 3.1.2(in future 3.2.3), Hibernate 4.1 final.
I am new to Sprind Data JPA. I have tow Table Release_date_type and Cache_media which entities are as follows :
ReleaseAirDate.java
#Entity
#Table(name = "Release_date_type")
public class ReleaseDateType {
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
private Integer release_date_type_id;
#Column
private Integer sort_order;
#Column
private String description;
#Column
private String data_source_type;
#Column(nullable = true)
private Integer media_Id;
#Column
private String source_system; with getters and setters..
and CacheMedia as
#Entity
#Table(name = "Cache_Media")
public class CacheMedia {
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
private Integer id;
#Column(name="code")
private String code;
#Column(name="POSITION")
private Integer position;
#Column(name="DESCRIPTION")
private String media_Description; with setter and getters.
Now my repository interface is as follows :
public interface ReleaseDateTypeRepository extends CrudRepository<ReleaseDateType, Long>{ }
Now i want to write a method(Query) in ReleaseDateTypeRepository interface which can get all the data from Release_Date_Type table including appropriate media_description from Table 'Cache_Media' based on media_id of Release_date_type table.
So my select (SQL)query looks like
SELECT * from Release_Date_Type r left join Cache_Media c on r.media_id=c.id
I don't know how to map entities.
I tried so many thing but not luck.
Any help is appreciated.
Its not the answer for joining via Hibernate, but alternatively you can create a view with your join and map the view to your objects

Categories