I'm currently using Eclipse Luna for J2EE Developers to generate JPA entities from a schema. The generated entities are being created with primitives (int) instead of wrappers (Integer) which is an issue for nullable fields. Is there a way to change this? There doesn't seem to be an option for it in the wizard and I have had no luck in my search so far.
Here is a snippet of a generated class as an example:
#Entity
#Table(name="facility")
#NamedQuery(name="Facility.findAll", query="SELECT f FROM Facility f")
public class Facility implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name="census_code")
private String censusCode;
#Temporal(TemporalType.TIMESTAMP)
private Date created;
private Timestamp modified;
private String name;
#Column(name="portal_id")
private int portalId;
#Column(name="short_name")
private String shortName;
...
}
Obviously id should remain a primitive but in this case portalId should be using the wrapper class.
Any suggestions are welcomed.
Related
I'm trying to implement entity auditing in my Java Spring Boot project using spring-data-envers. All the entities are being created as they should, but I've come up against a brick wall when executing the query.
parentRepository.findRevisions(id).stream().map(Parent::getEntity).collect(Collectors.toList());
During this select the repository is supposed to fetch info also from the child entity, instead I get unable to find <child object> with {id}.
According to my experiments categoryId is being searched in the Category_Aud table, instead of the actual table with desired data.
Code snippets:
#Data
#Entity
#Audited
#NoArgsConstructor
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Enumerated(EnumType.STRING)
private Status status;
#Enumerated(EnumType.STRING)
private Type requestType;
private String fullName;
#ManyToOne
#JoinColumn(name = "child_id")
private Child child;
}
#Data
#Entity
#Audited
#NoArgsConstructor
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
}
I've extended Parent with RevisionRepository
#Repository
public interface ParentRepository extends RevisionRepository<Parent, Long, Long>, JpaRepository<Parent, Long>
And annotated my SpringBootApplication entry class with:
#EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
I couldn't find any explanation for this so far, how can make parentRepository get what I need?
The underlying problem here is that the reference from a versioned entity isn't really properly defined. Which variant of the reference should be returned? The one at the start of the version you use as a basis, the one at the end? The one that exists right now?
There are scenarios for which each variant makes sense.
Therefor you have to query the revisions yourself and can't simply navigate to them.
How can I share a column between two FKs to the same reference table?
I have four entities: Player,Team, TeamPlayer and PlayerScore.
Now here is the use case:
Every batsman in cricket (sorry for a non-global example) playing for a specific team will be scoring when he has a partner-batsman called the runner. Now, the PlayerScore entity needs to capture this information.
So, I must ensure that both the batsman and his partner are playing for the same team. I can use this table to understand which pairs of batsman have been the performing the best. In exact terms, I need two references from PlayerScore Entity to the TeamPlayer entity. Both of them share exactly one column, team. How can I achieve this?
Here are the four classes:
#Entity
#Table(name="team")
public class Team {
#Id
private int id;
#Column(name="name",length=50)
private String name;
}
#Entity
#Table(name="player")
public class Player {
#Id
private int id;
#Column(name="name",length=50)
private String name;
}
#Entity
#Table(name="team_player")
public class TeamPlayer {
#EmbeddedId
private TeamPlayerPK id;
#ManyToOne(targetEntity=Player.class)
#JoinColumn(name="player")
private Player player;
#ManyToOne(targetEntity=Team.class)
#JoinColumn(name="team")
private Team team;
#Column(name="name",length=50)
private String name;
#Embeddable
public static class TeamPlayerPK implements Serializable
{
private static final long serialVersionUID = 1L;
private int team;
private int player;
}
}
#Entity
#Table(name="player_score")
public class PlayerScore {
#Id
private int scoreId;
#ManyToOne(targetEntity=TeamPlayer.class)
#JoinColumns(value={#JoinColumn(name="team",referencedColumnName="team"),#JoinColumn(name="batsmen",referencedColumnName="player")})
private TeamPlayer batsman;
#ManyToOne(targetEntity=TeamPlayer.class)
#JoinColumns(value={#JoinColumn(name="team",referencedColumnName="team"),#JoinColumn(name="runner",referencedColumnName="player")})
private TeamPlayer runner;
private int score;
#Temporal(TemporalType.DATE)
private Date matchDate;
}
EDIT 1: Added the Mysql WB model as suggested in the comment
EDIT 2: First unsuccessful attempt:
The Team, and Player entities remain as above. But the TeamPlayer has been changed as follows:
#ManyToOne(targetEntity=Player.class)
#PrimaryKeyJoinColumn(name="player",referencedColumnName="id")
private Player player;
The #JoinColumn has been changed to #PrimaryKeyJoinColumn
The annotations for runner field in the PlayerScore entity is changed as follows:
#ManyToOne(targetEntity=TeamPlayer.class)
#JoinColumns(value={#JoinColumn(name="team",referencedColumnName="team",insertable=false,updatable=false),#JoinColumn(name="runner",referencedColumnName="player",insertable=true,updatable=true)})
private TeamPlayer runner;
The expectation is that the FK reference for runner is also generated. THe code compiles and Eclipselink goes thru the generation but the foreign key for runner is NOT generated. In search of success yet...
I need to join a table and a view in a JPA query. The query won't compile because the view columns can't be identified.
Any suggestions are greatly appreciated.
Updated with parent entity and consistent naming
The query is:
select count(m.id)
from MultiSpeedMotor m,
MultiSpeedQuery q1
where m.id = q1.motorId
and q1.power = 10
The errors are:
The state field path 'q1.motorId' cannot be resolved to a valid type.
The state field path 'q1.power' cannot be resolved to a valid type.
I am working with a legacy database that has a denormalized table similar to this
Long motorId
Long id
Double hi_power
Double lo_power
I have used a view with a union query to normalize this table into
Long motorId
Long id
Long hi
Double power
To model the view of union query in JPA, I have used an #IdClass
public class MultiSpeedQueryId implements Serializable {
private static final long serialVersionUID = -7996931190943239257L;
private Long motorId;
private Long id;
private Long hi;
...
}
#Entity
#Table(name = "multi_speed_query")
#IdClass(MultiSpeedQueryId.class)
public class MultiSpeedQuery implements IMultiSpeedQuery {
#Id
#Column(name = "motor_id")
private Long motorId;
#Id
private Long id;
#Id
private Long hi;
private Double power;
...
}
The parent Entity is mapped as:
#Entity
#Table(name = "multi_speed_motor")
public class MultiSpeedMotor implements Serializable, IMultiSpeedMotor {
private static final long serialVersionUID = 3019928176257499187L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
}
The query is correct as written.
You CAN join Entities with no pre-defined relationship by using the syntax.
where a.id = b.joinField
The issue was much simpler. I missed part of the JPA error log that was telling the real problem.
The abstract schema type 'MultiSpeedQuery' is unknown.
Once I added the Entity to the persistence.xml, the query, as originally written, worked perfectly.
I have a Spring project where I access the database using Spring Data REST (using http://spring.io/guides/gs/accessing-data-rest/)
#RepositoryRestResource(collectionResourceRel = "test", path = "test")
public interface TestRepository extends PagingAndSortingRepository<Test, Long> {
#Query("SELECT max(p.lastUpdatedDate) FROM Test p")
Date findLastUpdatedDate();
}
When I try to access the above method to get the MAX date using the URL localhost:8080/test/search/findLastUpdatedDate, I get the error
{"cause":null,"message":"Cannot create self link for class java.sql.Timestamp! No persistent entity found!"}
Please suggest how can I get the max lastUpdatedDate from the Test table. Thanks!
Here is my Test class:
#Entity
#Table(name="test")
public class Test implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String col1;
private String col2;
private String status;
#Column(name = "last_updated_date")
private Date lastUpdatedDate;
// getters, setters, hashcode, equals, toString methods are written
}
You need to use the #Temporal annotation on dates.
You should also use java.util.Date or Joda time instead of java.sql.Timestamp
Spring Data JPA also has built-in created/modified timestamps, so you should look into that:
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#auditing
I got two entities like this (second one have a relation with first one) :
#Entity
#Table(name="FOA_ADRESSE_ICX")
public class FoaAdresseIcx implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="ID_ADRESSE", unique=true, nullable=false, precision=5)
private long idAdresse;
#Column(length=32)
private String bat;
#Column(name="COD_POSTAL", length=5)
private String codPostal;
// getters and setters ....
}
#Entity
#Table(name="FOA_INFOS_ICX")
public class FoaInfosIcx implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="COD_ICX", unique=true, nullable=false, length=8)
private String codIcx;
#Column(name="DATE_RAFFRAICHISEMENT")
#Temporal(TemporalType.TIMESTAMP)
private Date dateRaffraichisement;
#Column(name="LIB_AGENCE", nullable=false, length=98)
private String libAgence;
//uni-directional many-to-one association to FoaAdresseIcx
#ManyToOne
#JoinColumn(name="ID_ADRESSE", nullable=false)
private FoaAdresseIcx foaAdresseIcx;
// getters and setters....
}
I got a problem with the merge :
myEntityMgr.merge(myFoaInfosIcx);
Got this exception :
GRAVE: EJB Exception: : javax.persistence.EntityNotFoundException: Unable to find com.groupama.middlgan.entities.FoaAdresseIcx with id 0
In myFoaInfosIcx id is 0 because I don't initialise it, because I want JPA to create new FoaAdresseIcx in database if doesn't exist.
How can I do that ?
Using primitive types as DB ids has the downside you are currently experiencing. The default value is 0, which is a perfectly valid value for a DB id.
The persistence provider assumes that the entity is not new, but detached and behaves accordingly.
A solution is to use wrapper classes (or other non-primitive classes like UUID) as ids - Long in you case. Unless explicitly instantiated, the id attributes will be null and the provider will correctly identify an entity as new.