随时随地学习Spring及其所有工具。不确定如何使用PK而不是String。 tickets = repository.findOne(tk.getSerial());想要主键但无法找到正确的方法吗?
主界面:
package com.boot;
import com.boot.model.Tickets;
import com.boot.repository.TicketsRepository;
import com.boot.service.TicketsEditor;
import com.vaadin.annotations.Theme;
import com.vaadin.data.util.BeanContainer;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.sass.internal.util.StringUtil;
import com.vaadin.server.FontAwesome;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
/**
* Created by Ryan on 7/28/2016.
*/
@SpringUI
@Theme("valo")
public class TicketsUI extends UI {
private final TicketsRepository repository;
private final TicketsEditor editor;
private final Grid grid;
private final TextField filter;
private final TextField invoiceFilter;
private final Button addNewBtn;
@Autowired
public TicketsUI(TicketsRepository tkRepo, TicketsEditor tkEditor) {
this.repository = tkRepo;
this.editor = tkEditor;
this.grid = new Grid();
this.filter = new TextField();
this.invoiceFilter = new TextField();
this.addNewBtn = new Button("New game", FontAwesome.PLUS);
}
@Override
protected void init(VaadinRequest request) {
// build layout
HorizontalLayout actions = new HorizontalLayout(filter, invoiceFilter, addNewBtn);
VerticalLayout mainLayout = new VerticalLayout(actions, grid, editor);
setContent(mainLayout);
// Configure layouts and components
actions.setSpacing(true);
mainLayout.setMargin(true);
mainLayout.setSpacing(true);
grid.setHeight(500,Unit.PIXELS);
grid.setWidth(1800,Unit.PIXELS);
grid.setColumns("serial", "datePlaced", "dateRemoved","unsoldAmt", "actualGross","actualPrizes",
"actualNet", "bin", "inplay", "closed", "unsoldTickets", "lastSaleRem", "prizeRem1", "prizeRem2",
"prizeRem3", "prizeRem4", "prizeRem5","prizeRem6", "prizeRem7", "prizeRem8","prizeRem9", "prizeRem10", "prizeRem11", "prizeRem12", "prizeRem13", "prizeRem14", "prizeRem15",
"gameTemplatesPartNum", "datePurch", "invoiceNum", "type");
filter.setInputPrompt("Filter by serial");
filter.addTextChangeListener(e -> listTickets(e.getText()));
// invoiceFilter.setInputPrompt("Filter by invoice");
// invoiceFilter.addTextChangeListener(e -> listTickets(e.getText()));
//grid.setContainerDataSource(new BeanItemContainer(Tickets.class, repository.findByInvoiceNum()));
// Connect selected Customer to editor or hide if none is selected
grid.addSelectionListener(e -> {
if (e.getSelected().isEmpty()) {
editor.setVisible(false);
}
else {
editor.editTicket((Tickets) grid.getSelectedRow());
}
});
// Instantiate and edit new Customer the new button is clicked
addNewBtn.addClickListener(e -> editor.editTicket(new Tickets()));
// Listen changes made by the editor, refresh data from backend
editor.setChangeHandler(() -> {
editor.setVisible(false);
listTickets(filter.getValue());
});
// Initialize listing
listTickets(null);
}
private void listTickets(String text){
if (StringUtils.isEmpty(text)) {
grid.setContainerDataSource(
new BeanItemContainer(Tickets.class, repository.findAll()));
}else
{
grid.setContainerDataSource(new BeanItemContainer(Tickets.class, repository.findBySerial(text)));
}
}
}
票务
package com.boot.model;
import javax.persistence.*;
import java.sql.Date;
/**
* Created by Ryan on 7/26/2016.
*/
@Entity
@IdClass(TicketsPK.class)
public class Tickets {
private String serial;
private Date datePlaced;
private Date dateRemoved;
private Integer unsoldAmt;
private Integer actualGross;
private Integer actualPrizes;
private Integer actualNet;
private Integer bin;
private Byte inplay;
private Integer closed;
private Integer unsoldTickets;
private Byte lastSaleRem;
private Integer prizeRem1;
private Integer prizeRem2;
private Integer prizeRem3;
private Integer prizeRem4;
private Integer prizeRem5;
private Integer prizeRem6;
private Integer prizeRem7;
private Integer prizeRem8;
private Integer prizeRem9;
private Integer prizeRem10;
private Integer prizeRem11;
private Integer prizeRem12;
private Integer prizeRem13;
private Integer prizeRem14;
private Integer prizeRem15;
private String gameTemplatesPartNum;
private Date datePurch;
private String invoiceNum;
private Integer type;
@Id
@Column(name = "Serial")
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
@Basic
@Column(name = "Date_placed")
public Date getDatePlaced() {
return datePlaced;
}
public void setDatePlaced(Date datePlaced) {
this.datePlaced = datePlaced;
}
@Basic
@Column(name = "Date_removed")
public Date getDateRemoved() {
return dateRemoved;
}
public void setDateRemoved(Date dateRemoved) {
this.dateRemoved = dateRemoved;
}
@Basic
@Column(name = "Unsold_amt")
public Integer getUnsoldAmt() {
return unsoldAmt;
}
public void setUnsoldAmt(Integer unsoldAmt) {
this.unsoldAmt = unsoldAmt;
}
@Basic
@Column(name = "Actual_gross")
public Integer getActualGross() {
return actualGross;
}
public void setActualGross(Integer actualGross) {
this.actualGross = actualGross;
}
@Basic
@Column(name = "Actual_prizes")
public Integer getActualPrizes() {
return actualPrizes;
}
public void setActualPrizes(Integer actualPrizes) {
this.actualPrizes = actualPrizes;
}
@Basic
@Column(name = "Actual_net")
public Integer getActualNet() {
return actualNet;
}
public void setActualNet(Integer actualNet) {
this.actualNet = actualNet;
}
@Basic
@Column(name = "Bin")
public Integer getBin() {
return bin;
}
public void setBin(Integer bin) {
this.bin = bin;
}
@Basic
@Column(name = "Inplay")
public Byte getInplay() {
return inplay;
}
public void setInplay(Byte inplay) {
this.inplay = inplay;
}
@Basic
@Column(name = "Closed")
public Integer getClosed() {
return closed;
}
public void setClosed(Integer closed) {
this.closed = closed;
}
@Basic
@Column(name = "Unsold_tickets")
public Integer getUnsoldTickets() {
return unsoldTickets;
}
public void setUnsoldTickets(Integer unsoldTickets) {
this.unsoldTickets = unsoldTickets;
}
@Basic
@Column(name = "Last_sale_rem")
public Byte getLastSaleRem() {
return lastSaleRem;
}
public void setLastSaleRem(Byte lastSaleRem) {
this.lastSaleRem = lastSaleRem;
}
@Basic
@Column(name = "Prize_rem1")
public Integer getPrizeRem1() {
return prizeRem1;
}
public void setPrizeRem1(Integer prizeRem1) {
this.prizeRem1 = prizeRem1;
}
@Basic
@Column(name = "Prize_rem2")
public Integer getPrizeRem2() {
return prizeRem2;
}
public void setPrizeRem2(Integer prizeRem2) {
this.prizeRem2 = prizeRem2;
}
@Basic
@Column(name = "Prize_rem3")
public Integer getPrizeRem3() {
return prizeRem3;
}
public void setPrizeRem3(Integer prizeRem3) {
this.prizeRem3 = prizeRem3;
}
@Basic
@Column(name = "Prize_rem4")
public Integer getPrizeRem4() {
return prizeRem4;
}
public void setPrizeRem4(Integer prizeRem4) {
this.prizeRem4 = prizeRem4;
}
@Basic
@Column(name = "Prize_rem5")
public Integer getPrizeRem5() {
return prizeRem5;
}
public void setPrizeRem5(Integer prizeRem5) {
this.prizeRem5 = prizeRem5;
}
@Basic
@Column(name = "Prize_rem6")
public Integer getPrizeRem6() {
return prizeRem6;
}
public void setPrizeRem6(Integer prizeRem6) {
this.prizeRem6 = prizeRem6;
}
@Basic
@Column(name = "Prize_rem7")
public Integer getPrizeRem7() {
return prizeRem7;
}
public void setPrizeRem7(Integer prizeRem7) {
this.prizeRem7 = prizeRem7;
}
@Basic
@Column(name = "Prize_rem8")
public Integer getPrizeRem8() {
return prizeRem8;
}
public void setPrizeRem8(Integer prizeRem8) {
this.prizeRem8 = prizeRem8;
}
@Basic
@Column(name = "Prize_rem9")
public Integer getPrizeRem9() {
return prizeRem9;
}
public void setPrizeRem9(Integer prizeRem9) {
this.prizeRem9 = prizeRem9;
}
@Basic
@Column(name = "Prize_rem10")
public Integer getPrizeRem10() {
return prizeRem10;
}
public void setPrizeRem10(Integer prizeRem10) {
this.prizeRem10 = prizeRem10;
}
@Basic
@Column(name = "Prize_rem11")
public Integer getPrizeRem11() {
return prizeRem11;
}
public void setPrizeRem11(Integer prizeRem11) {
this.prizeRem11 = prizeRem11;
}
@Basic
@Column(name = "Prize_rem12")
public Integer getPrizeRem12() {
return prizeRem12;
}
public void setPrizeRem12(Integer prizeRem12) {
this.prizeRem12 = prizeRem12;
}
@Basic
@Column(name = "Prize_rem13")
public Integer getPrizeRem13() {
return prizeRem13;
}
public void setPrizeRem13(Integer prizeRem13) {
this.prizeRem13 = prizeRem13;
}
@Basic
@Column(name = "Prize_rem14")
public Integer getPrizeRem14() {
return prizeRem14;
}
public void setPrizeRem14(Integer prizeRem14) {
this.prizeRem14 = prizeRem14;
}
@Basic
@Column(name = "Prize_rem15")
public Integer getPrizeRem15() {
return prizeRem15;
}
public void setPrizeRem15(Integer prizeRem15) {
this.prizeRem15 = prizeRem15;
}
@Id
@Column(name = "game_templates_part_num")
public String getGameTemplatesPartNum() {
return gameTemplatesPartNum;
}
public void setGameTemplatesPartNum(String gameTemplatesPartNum) {
this.gameTemplatesPartNum = gameTemplatesPartNum;
}
@Basic
@Column(name = "date_purch")
public Date getDatePurch() {
return datePurch;
}
public void setDatePurch(Date datePurch) {
this.datePurch = datePurch;
}
@Basic
@Column(name = "invoice_num")
public String getInvoiceNum() {
return invoiceNum;
}
public void setInvoiceNum(String invoiceNum) {
this.invoiceNum = invoiceNum;
}
@Basic
@Column(name = "type")
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
}
TicketsPK
package com.boot.model;
import javax.persistence.Column;
import javax.persistence.Id;
import java.io.Serializable;
/**
* Created by Ryan on 7/26/2016.
*/
public class TicketsPK implements Serializable {
private String serial;
private String gameTemplatesPartNum;
@Column(name = "Serial")
@Id
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
@Column(name = "game_templates_part_num")
@Id
public String getGameTemplatesPartNum() {
return gameTemplatesPartNum;
}
public void setGameTemplatesPartNum(String gameTemplatesPartNum) {
this.gameTemplatesPartNum = gameTemplatesPartNum;
}
}
回购
package com.boot.repository;
import com.boot.model.Tickets;
import com.boot.model.TicketsPK;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
* Created by Ryan on 7/28/2016.
*/
public interface TicketsRepository extends JpaRepository<Tickets, String>{
List<Tickets> findBySerial (String serial);
}
Pruned stacktrace:
org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class com.boot.model.Tickets. Expected: class com.boot.model.TicketsPK, got class java.lang.String; nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class com.boot.model.Tickets. Expected: class com.boot.model.TicketsPK, got class java.lang.String
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384) ~[spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:227) ~[spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) ~[spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~[spring-tx-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[spring-tx-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) ~[spring-tx-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131) ~[spring-data-jpa-1.9.2.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at com.sun.proxy.$Proxy80.findOne(Unknown Source) ~[na:na]
at com.boot.service.TicketsEditor.editTicket(TicketsEditor.java:88) ~[classes/:na]
at com.boot.TicketsUI.lambda$init$ca60a5c0$1(TicketsUI.java:75) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
at com.boot.TicketsUI.lambda$init$ca60a5c0$1(TicketsUI.java:75) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
TicketEditor
package com.boot.service;
import com.boot.model.Tickets;
import com.boot.model.TicketsPK;
import com.boot.repository.TicketsRepository;
import com.vaadin.data.fieldgroup.BeanFieldGroup;
import com.vaadin.event.ShortcutAction;
import com.vaadin.server.FontAwesome;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.*;
import com.vaadin.ui.components.calendar.CalendarComponentEvents;
import com.vaadin.ui.themes.ValoTheme;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by Ryan on 7/28/2016.
*/
@SpringComponent
@UIScope
public class TicketsEditor extends VerticalLayout{
private final TicketsRepository repository;
private Tickets tickets;
//TextField gameName = new TextField("Game Name");
TextField serial = new TextField("Serial");
DateField datePlaced = new DateField("Date placed");
DateField dateRemoved = new DateField("Date Removed");
TextField unsoldAmt = new TextField("Unsold Amount");
TextField actualGross = new TextField("Actual Gross");
TextField actualPrizes = new TextField("Actual Prizes");
TextField actualNet = new TextField("Actual Net");
TextField bin = new TextField("Bin");
TextField inplay = new TextField("Inplay");
TextField closed = new TextField("Closed");
TextField unsoldTickets = new TextField("Unsold Tickets");
TextField lastSaleRem = new TextField("Last Sale Remaining");
TextField prizeRem1 = new TextField("Prize Remaining 1");
TextField prizeRem2 = new TextField("Prize Remaining 2");
TextField prizeRem3 = new TextField("Prize Remaining 3");
TextField prizeRem4 = new TextField("Prize Remaining 4");
TextField prizeRem5 = new TextField("Prize Remaining 5");
TextField prizeRem6 = new TextField("Prize Remaining 6");
TextField prizeRem7 = new TextField("Prize Remaining 7");
TextField prizeRem8 = new TextField("Prize Remaining 8");
TextField prizeRem9 = new TextField("Prize Remaining 9");
TextField prizeRem10 = new TextField("Prize Remaining 10");
TextField prizeRem11 = new TextField("Prize Remaining 11");
TextField prizeRem12 = new TextField("Prize Remaining 12");
TextField prizeRem13 = new TextField("Prize Remaining 13");
TextField prizeRem14 = new TextField("Prize Remaining 14");
TextField prizeRem15 = new TextField("Prize Remaining 15");
TextField gameTemplatesPartNum = new TextField("Part Number");
DateField datePurchased = new DateField("Date Purchased");
TextField invoice = new TextField("Invoice");
TextField type = new TextField("Type");
/* Action buttons */
Button save = new Button("Save", FontAwesome.SAVE);
Button cancel = new Button("Cancel");
Button delete = new Button("Delete", FontAwesome.TRASH_O);
CssLayout actions = new CssLayout(save, cancel, delete);
@Autowired
public TicketsEditor(TicketsRepository repository){
this.repository = repository;
addComponents(serial,datePlaced,dateRemoved, unsoldAmt, actualGross, actualPrizes, actualNet,bin,inplay,
closed, unsoldTickets, lastSaleRem, prizeRem1, prizeRem2, prizeRem3, prizeRem4, prizeRem5, prizeRem6,
prizeRem7, prizeRem8, prizeRem9, prizeRem10, prizeRem11, prizeRem12, prizeRem13, prizeRem14, prizeRem15,
actions);
setSpacing(true);
actions.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
save.setStyleName(ValoTheme.BUTTON_PRIMARY);
save.setClickShortcut(ShortcutAction.KeyCode.ENTER);
save.addClickListener(e -> repository.saveAndFlush(tickets));
delete.addClickListener(e -> repository.delete(tickets));
cancel.addClickListener(e -> editTicket(tickets));
setVisible(false);
}
public interface ChangeHandler{
void onChange();
}
public final void editTicket(Tickets tk){
final boolean persisted = tk.getSerial() != null;
if(persisted){
tickets = repository.findOne(tk.getSerial());
}else{
tickets = tk;
}
cancel.setVisible(persisted);
BeanFieldGroup.bindFieldsUnbuffered(tickets, this);
setVisible(true);
save.focus();
serial.selectAll();
}
public void setChangeHandler(ChangeHandler h){
save.addClickListener(e -> h.onChange());
delete.addClickListener(e -> h.onChange());
}
}
答案 0 :(得分:0)
em.find
接收IdClass
的实例。因此,在您的情况下,您需要传入TicketsPK
的实例,而不是其中的一个组件。